Remove GetConnectedRoads from IntersectionGenerator

This commit is contained in:
Michael Krasnyk 2017-12-03 21:32:17 +01:00
parent cc1a5ea78d
commit db7c76d04d
31 changed files with 573 additions and 633 deletions

View File

@ -18,6 +18,10 @@ class DrivewayHandler final : public IntersectionHandler
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table);

View File

@ -44,14 +44,6 @@ inline auto makeCompareShapeDataByBearing(const double base_bearing)
};
}
inline auto makeCompareShapeDataAngleToBearing(const double base_bearing)
{
return [base_bearing](const auto &lhs, const auto &rhs) {
return util::bearing::angleBetween(lhs.bearing, base_bearing) <
util::bearing::angleBetween(rhs.bearing, base_bearing);
};
}
inline auto makeCompareAngularDeviation(const double angle)
{
return [angle](const auto &lhs, const auto &rhs) {

View File

@ -44,26 +44,6 @@ class IntersectionGenerator
const std::vector<util::Coordinate> &coordinates,
const CompressedEdgeContainer &compressed_edge_container);
// For a source node `a` and a via edge `ab` creates an intersection at target `b`.
//
// a . . . b . .
// .
// .
//
IntersectionView operator()(const NodeID nid, const EdgeID via_eid) const;
/*
* Compute the shape of an intersection, returning a set of connected roads, without any further
* concern for which of the entries are actually allowed.
* The shape also only comes with turn bearings, not with turn angles. All turn angles will be
* set to zero
*/
OSRM_ATTR_WARN_UNUSED
IntersectionShape
ComputeIntersectionShape(const NodeID center_node,
const boost::optional<NodeID> sorting_base = boost::none,
bool use_low_precision_angles = false) const;
// Graph Compression cannot compress every setting. For example any barrier/traffic light cannot
// be compressed. As a result, a simple road of the form `a ----- b` might end up as having an
// intermediate intersection, if there is a traffic light in between. If we want to look farther
@ -75,49 +55,12 @@ class IntersectionGenerator
IntersectionGenerationParameters SkipDegreeTwoNodes(const NodeID starting_node,
const EdgeID via_edge) const;
// Allow access to the coordinate extractor for all owners
const CoordinateExtractor &GetCoordinateExtractor() const;
// Check for restrictions/barriers and generate a list of valid and invalid turns present at
// the node reached from `from_node` via `via_eid`. The resulting candidates have to be analysed
// for their actual instructions later on.
// The switch for `use_low_precision_angles` enables a faster mode that will procude less
// accurate coordinates. It should be good enough to check order of turns, find straightmost
// turns. Even good enough to do some simple angle verifications. It is mostly available to
// allow for faster graph traversal in the extraction phase.
OSRM_ATTR_WARN_UNUSED
IntersectionView GetConnectedRoads(const NodeID from_node,
const EdgeID via_eid,
const bool use_low_precision_angles = false) const;
/*
* To be used in the road network, we need to check for valid/restricted turns. These two
* functions transform a basic intersection / a normalised intersection into the
* correct view when entering via a given edge.
*/
OSRM_ATTR_WARN_UNUSED
IntersectionView
TransformIntersectionShapeIntoView(const NodeID previous_node,
const EdgeID entering_via_edge,
const IntersectionShape &intersection) const;
// version for normalised intersection
OSRM_ATTR_WARN_UNUSED
IntersectionView TransformIntersectionShapeIntoView(
const NodeID previous_node,
const EdgeID entering_via_edge,
const IntersectionShape &normalised_intersection,
const IntersectionShape &intersection,
const std::vector<IntersectionNormalizationOperation> &merging_map) const;
private:
const util::NodeBasedDynamicGraph &node_based_graph;
const EdgeBasedNodeDataContainer &node_data_container;
const RestrictionMap &restriction_map;
const std::unordered_set<NodeID> &barrier_nodes;
const std::vector<util::Coordinate> &coordinates;
// own state, used to find the correct coordinates along a road
const CoordinateExtractor coordinate_extractor;
};
} // namespace guidance

View File

@ -4,6 +4,7 @@
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/node_based_graph_walker.hpp"
#include "extractor/intersection/intersection_analysis.hpp"
#include "extractor/query_node.hpp"
#include "extractor/suffix_table.hpp"
@ -34,7 +35,11 @@ class IntersectionHandler
public:
IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator);
@ -52,7 +57,11 @@ class IntersectionHandler
protected:
const util::NodeBasedDynamicGraph &node_based_graph;
const EdgeBasedNodeDataContainer &node_data_container;
const std::vector<util::Coordinate> &coordinates;
const std::vector<util::Coordinate> &node_coordinates;
const extractor::CompressedEdgeContainer &compressed_geometries;
const RestrictionMap &node_restriction_map;
const std::unordered_set<NodeID> &barrier_nodes;
const guidance::TurnLanesIndexedArray &turn_lanes_data;
const util::NameTable &name_table;
const SuffixTable &street_name_suffix_table;
const IntersectionGenerator &intersection_generator;
@ -571,7 +580,15 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
node_at_intersection, intersection[0].eid);
if (node_based_graph.GetTarget(parameters.via_eid) == node_at_intersection)
return {};
return intersection_generator.GetConnectedRoads(parameters.nid, parameters.via_eid);
return intersection::getConnectedRoads(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{parameters.nid, parameters.via_eid});
}();
if (!previous_intersection.empty())

View File

@ -1,7 +1,10 @@
#ifndef OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS
#define OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS
#include "extractor/compressed_edge_container.hpp"
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/restriction_index.hpp"
#include "util/coordinate.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
@ -9,6 +12,7 @@
#include <cstdint>
#include <functional>
#include <limits>
#include <unordered_set>
#include <vector>
namespace osrm
@ -39,6 +43,10 @@ class MergableRoadDetector
MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const IntersectionGenerator &intersection_generator,
const CoordinateExtractor &coordinate_extractor,
const util::NameTable &name_table,
@ -159,6 +167,10 @@ class MergableRoadDetector
const util::NodeBasedDynamicGraph &node_based_graph;
const EdgeBasedNodeDataContainer &node_data_container;
const std::vector<util::Coordinate> &node_coordinates;
const extractor::CompressedEdgeContainer &compressed_geometries;
const RestrictionMap &node_restriction_map;
const std::unordered_set<NodeID> &barrier_nodes;
const guidance::TurnLanesIndexedArray &turn_lanes_data;
const IntersectionGenerator &intersection_generator;
const CoordinateExtractor &coordinate_extractor;

View File

@ -26,6 +26,10 @@ class MotorwayHandler : public IntersectionHandler
MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator);

View File

@ -2,7 +2,9 @@
#define OSRM_EXTRACTOR_GUIDANCE_NODE_BASED_GRAPH_WALKER
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/coordinate_extractor.hpp"
#include "extractor/guidance/turn_lane_data.hpp"
#include "extractor/intersection/intersection_analysis.hpp"
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/node_based_graph.hpp"
@ -29,7 +31,11 @@ class NodeBasedGraphWalker
public:
NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const IntersectionGenerator &intersection_generator);
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data);
/*
* the returned node-id, edge-id are either the last ones used, just prior accumulator
@ -48,7 +54,11 @@ class NodeBasedGraphWalker
private:
const util::NodeBasedDynamicGraph &node_based_graph;
const EdgeBasedNodeDataContainer &node_data_container;
const IntersectionGenerator &intersection_generator;
const std::vector<util::Coordinate> &node_coordinates;
const extractor::CompressedEdgeContainer &compressed_geometries;
const RestrictionMap &node_restriction_map;
const std::unordered_set<NodeID> &barrier_nodes;
const guidance::TurnLanesIndexedArray &turn_lanes_data;
};
/*
@ -149,7 +159,13 @@ struct SelectStraightmostRoadByNameAndOnlyChoice
struct IntersectionFinderAccumulator
{
IntersectionFinderAccumulator(const std::uint8_t hop_limit,
const IntersectionGenerator &intersection_generator);
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data);
// true if the path has traversed enough distance
bool terminate();
@ -159,13 +175,19 @@ struct IntersectionFinderAccumulator
std::uint8_t hops;
const std::uint8_t hop_limit;
// we need to be able to look-up the intersection
const IntersectionGenerator &intersection_generator;
// the result we are looking for
NodeID nid;
EdgeID via_edge_id;
IntersectionView intersection;
private:
const util::NodeBasedDynamicGraph &node_based_graph;
const EdgeBasedNodeDataContainer &node_data_container;
const std::vector<util::Coordinate> &node_coordinates;
const extractor::CompressedEdgeContainer &compressed_geometries;
const RestrictionMap &node_restriction_map;
const std::unordered_set<NodeID> &barrier_nodes;
const guidance::TurnLanesIndexedArray &turn_lanes_data;
};
template <class accumulator_type, class selector_type>
@ -199,9 +221,15 @@ NodeBasedGraphWalker::TraverseRoad(NodeID current_node_id,
return {};
// look at the next intersection
const constexpr auto LOW_PRECISION = true;
const auto next_intersection = intersection_generator.GetConnectedRoads(
current_node_id, current_edge_id, LOW_PRECISION);
const auto next_intersection =
intersection::getConnectedRoads(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{current_node_id, current_edge_id});
// don't follow u-turns or go past our initial intersection
if (next_intersection.size() <= 1)

View File

@ -42,7 +42,10 @@ class RoundaboutHandler : public IntersectionHandler
RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const CompressedEdgeContainer &compressed_edge_container,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator);
@ -80,7 +83,6 @@ class RoundaboutHandler : public IntersectionHandler
bool
qualifiesAsRoundaboutIntersection(const std::unordered_set<NodeID> &roundabout_nodes) const;
const CompressedEdgeContainer &compressed_edge_container;
const CoordinateExtractor coordinate_extractor;
};

View File

@ -28,6 +28,10 @@ class SliproadHandler final : public IntersectionHandler
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table);
@ -78,6 +82,8 @@ class SliproadHandler final : public IntersectionHandler
// The return value is guaranteed to not be larger than `threshold`.
static double scaledThresholdByRoadClass(const double max_threshold,
const RoadClassification &classification);
const CoordinateExtractor coordinate_extractor;
};
} // namespace guidance

View File

@ -31,11 +31,19 @@ class StatisticsHandler final : public IntersectionHandler
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
: IntersectionHandler(node_based_graph,
node_data_container,
coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator)

View File

@ -25,6 +25,10 @@ class SuppressModeHandler final : public IntersectionHandler
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table);

View File

@ -42,10 +42,11 @@ class TurnAnalysis
public:
TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const std::vector<util::Coordinate> &node_coordinates,
const CompressedEdgeContainer &compressed_edge_container,
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const CompressedEdgeContainer &compressed_edge_container,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table);
@ -61,8 +62,6 @@ class TurnAnalysis
const EdgeID via_eid,
const IntersectionView &intersection) const;
const IntersectionGenerator &GetIntersectionGenerator() const;
private:
const util::NodeBasedDynamicGraph &node_based_graph;
const IntersectionGenerator intersection_generator;

View File

@ -3,6 +3,7 @@
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/turn_lane_data.hpp"
#include "util/typedefs.hpp"
namespace osrm
@ -21,8 +22,13 @@ bool findPreviousIntersection(
const NodeID node,
const EdgeID via_edge,
const Intersection &intersection,
const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph, // query edge data
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
// output parameters, will be in an arbitrary state on failure
NodeID &result_node,
EdgeID &result_via_edge,

View File

@ -30,6 +30,10 @@ class TurnHandler : public IntersectionHandler
TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator);

View File

@ -74,6 +74,11 @@ class TurnLaneHandler
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
LaneDescriptionMap &lane_description_map,
const TurnAnalysis &turn_analysis,
util::guidance::LaneDataIdMap &id_map);
@ -90,6 +95,12 @@ class TurnLaneHandler
// lanes for a turn
const util::NodeBasedDynamicGraph &node_based_graph;
const EdgeBasedNodeDataContainer &node_data_container;
const std::vector<util::Coordinate> &node_coordinates;
const extractor::CompressedEdgeContainer &compressed_geometries;
const RestrictionMap &node_restriction_map;
const std::unordered_set<NodeID> &barrier_nodes;
const guidance::TurnLanesIndexedArray &turn_lanes_data;
std::vector<std::uint32_t> turn_lane_offsets;
std::vector<TurnLaneType::Mask> turn_lane_masks;
LaneDescriptionMap &lane_description_map;

View File

@ -26,6 +26,19 @@ IntersectionEdges getIncomingEdges(const util::NodeBasedDynamicGraph &graph,
IntersectionEdges getOutgoingEdges(const util::NodeBasedDynamicGraph &graph,
const NodeID intersection);
bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph,
const EdgeBasedNodeDataContainer &node_data_container,
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const IntersectionEdgeGeometries &geometries,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const IntersectionEdge &from,
const IntersectionEdge &to);
double findEdgeBearing(const IntersectionEdgeGeometries &geometries, const EdgeID &edge);
double findEdgeLength(const IntersectionEdgeGeometries &geometries, const EdgeID &edge);
std::pair<IntersectionEdgeGeometries, std::unordered_set<EdgeID>>
getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
const extractor::CompressedEdgeContainer &compressed_geometries,
@ -44,18 +57,15 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph,
const IntersectionEdges &outgoing_edges,
const std::unordered_set<EdgeID> &merged_edges);
bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph,
const EdgeBasedNodeDataContainer &node_data_container,
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const IntersectionEdgeGeometries &geometries,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const IntersectionEdge &from,
const IntersectionEdge &to);
double findEdgeBearing(const IntersectionEdgeGeometries &geometries, const EdgeID &edge);
double findEdgeLength(const IntersectionEdgeGeometries &geometries, const EdgeID &edge);
guidance::IntersectionView
getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const IntersectionEdge &incoming_edge);
}
}
}

View File

@ -423,42 +423,57 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
TurnDataExternalContainer turn_data_container;
// TODO: add a MergableRoadDetector instance, to be deleted later
SuffixTable street_name_suffix_table(scripting_environment);
const auto &turn_lanes_data = transformTurnLaneMapIntoArrays(lane_description_map);
guidance::CoordinateExtractor coordinate_extractor(
m_node_based_graph, m_compressed_edge_container, m_coordinates);
guidance::IntersectionGenerator intersection_generator(m_node_based_graph,
m_edge_based_node_container,
node_restriction_map,
m_barrier_nodes,
m_coordinates,
m_compressed_edge_container);
guidance::MergableRoadDetector mergable_road_detector(m_node_based_graph,
m_edge_based_node_container,
m_coordinates,
m_compressed_edge_container,
node_restriction_map,
m_barrier_nodes,
turn_lanes_data,
intersection_generator,
coordinate_extractor,
name_table,
street_name_suffix_table);
// Loop over all turns and generate new set of edges.
// Three nested loop look super-linear, but we are dealing with a (kind of)
// linear number of turns only.
SuffixTable street_name_suffix_table(scripting_environment);
guidance::TurnAnalysis turn_analysis(m_node_based_graph,
m_edge_based_node_container,
m_coordinates,
m_compressed_edge_container,
node_restriction_map,
m_barrier_nodes,
m_compressed_edge_container,
turn_lanes_data,
name_table,
street_name_suffix_table);
util::guidance::LaneDataIdMap lane_data_map;
guidance::lanes::TurnLaneHandler turn_lane_handler(m_node_based_graph,
m_edge_based_node_container,
m_coordinates,
m_compressed_edge_container,
node_restriction_map,
m_barrier_nodes,
turn_lanes_data,
lane_description_map,
turn_analysis,
lane_data_map);
// TODO: add a MergableRoadDetector instance, to be deleted later
guidance::CoordinateExtractor coordinate_extractor(
m_node_based_graph, m_compressed_edge_container, m_coordinates);
guidance::MergableRoadDetector mergable_road_detector(m_node_based_graph,
m_edge_based_node_container,
m_coordinates,
turn_analysis.GetIntersectionGenerator(),
coordinate_extractor,
name_table,
street_name_suffix_table);
bearing_class_by_node_based_node.resize(m_node_based_graph.GetNumberOfNodes(),
std::numeric_limits<std::uint32_t>::max());
const auto &turn_lanes_data = transformTurnLaneMapIntoArrays(lane_description_map);
// FIXME these need to be tuned in pre-allocated size
std::vector<TurnPenalty> turn_weight_penalties;
std::vector<TurnPenalty> turn_duration_penalties;

View File

@ -15,12 +15,20 @@ namespace guidance
DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
: IntersectionHandler(node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator)
@ -64,12 +72,12 @@ operator()(const NodeID nid, const EdgeID source_edge_id, Intersection intersect
});
(void)nid;
OSRM_ASSERT(road != intersection.end(), coordinates[nid]);
OSRM_ASSERT(road != intersection.end(), node_coordinates[nid]);
if (road->instruction == TurnInstruction::INVALID())
return intersection;
OSRM_ASSERT(road->instruction.type == TurnType::Turn, coordinates[nid]);
OSRM_ASSERT(road->instruction.type == TurnType::Turn, node_coordinates[nid]);
road->instruction.type =
isSameName(source_edge_id, road->eid) ? TurnType::NoTurn : TurnType::NewName;

View File

@ -31,214 +31,17 @@ const constexpr bool USE_LOW_PRECISION_MODE = true;
const constexpr bool USE_HIGH_PRECISION_MODE = !USE_LOW_PRECISION_MODE;
}
IntersectionGenerator::IntersectionGenerator(
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const std::vector<util::Coordinate> &coordinates,
const CompressedEdgeContainer &compressed_edge_container)
IntersectionGenerator::IntersectionGenerator(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const std::vector<util::Coordinate> &coordinates,
const CompressedEdgeContainer &)
: node_based_graph(node_based_graph), node_data_container(node_data_container),
restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates),
coordinate_extractor(node_based_graph, compressed_edge_container, coordinates)
restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates)
{
}
IntersectionView IntersectionGenerator::operator()(const NodeID from_node,
const EdgeID via_eid) const
{
return GetConnectedRoads(from_node, via_eid, USE_HIGH_PRECISION_MODE);
}
IntersectionShape
IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_intersection,
const boost::optional<NodeID> sorting_base,
const bool use_low_precision_angles) const
{
const auto intersection_degree = node_based_graph.GetOutDegree(node_at_center_of_intersection);
const util::Coordinate turn_coordinate = coordinates[node_at_center_of_intersection];
// compute bearings in a relatively small circle to prevent wrong roads order with true bearings
struct RoadWithInitialBearing
{
double bearing;
IntersectionShapeData road;
};
std::vector<RoadWithInitialBearing> initial_roads_ordering;
// reserve enough items (+ the possibly missing u-turn edge)
initial_roads_ordering.reserve(intersection_degree);
// number of lanes at the intersection changes how far we look down the road
const auto edge_range = node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection);
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)
.flags.road_classification.GetNumberOfLanes());
});
for (const EdgeID edge_connected_to_intersection :
node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection))
{
BOOST_ASSERT(edge_connected_to_intersection != SPECIAL_EDGEID);
const NodeID to_node = node_based_graph.GetTarget(edge_connected_to_intersection);
double bearing = 0.;
auto coordinates = coordinate_extractor.GetCoordinatesAlongRoad(
node_at_center_of_intersection, edge_connected_to_intersection, !INVERT, to_node);
const auto close_coordinate =
coordinate_extractor.ExtractCoordinateAtLength(2. /*m*/, coordinates);
const auto initial_bearing =
util::coordinate_calculation::bearing(turn_coordinate, close_coordinate);
const auto segment_length = util::coordinate_calculation::getLength(
coordinates.begin(),
coordinates.end(),
util::coordinate_calculation::haversineDistance);
const auto extract_coordinate = [&](const NodeID from_node,
const EdgeID via_eid,
const bool traversed_in_reverse,
const NodeID to_node) {
return (use_low_precision_angles || intersection_degree <= 2)
? coordinate_extractor.GetCoordinateCloseToTurn(
from_node, via_eid, traversed_in_reverse, to_node)
: coordinate_extractor.ExtractRepresentativeCoordinate(
from_node,
via_eid,
traversed_in_reverse,
to_node,
max_lanes_intersection,
std::move(coordinates));
};
// we have to look down the road a bit to get the correct turn
const auto coordinate_along_edge_leaving = extract_coordinate(
node_at_center_of_intersection, edge_connected_to_intersection, !INVERT, to_node);
bearing =
util::coordinate_calculation::bearing(turn_coordinate, coordinate_along_edge_leaving);
// OSM data sometimes contains duplicated nodes with identical coordinates, or
// because of coordinate precision rounding, end up at the same coordinate.
// It's impossible to calculate a bearing between these, so we log a warning
// that the data should be checked.
// The bearing calculation should return 0 in these cases, which may not be correct,
// but is at least not random.
if (turn_coordinate == coordinate_along_edge_leaving)
{
util::Log(logDEBUG) << "Zero length segment at " << coordinate_along_edge_leaving
<< " could cause invalid intersection exit bearing.";
BOOST_ASSERT(std::abs(bearing) <= 0.1);
}
initial_roads_ordering.push_back(
{initial_bearing, {edge_connected_to_intersection, bearing, segment_length}});
}
if (!initial_roads_ordering.empty())
{
const auto base_initial_bearing = [&]() {
if (sorting_base)
{
const auto itr = std::find_if(initial_roads_ordering.begin(),
initial_roads_ordering.end(),
[&](const auto &data) {
return node_based_graph.GetTarget(
data.road.eid) == *sorting_base;
});
if (itr != initial_roads_ordering.end())
return util::bearing::reverse(itr->bearing);
}
return util::bearing::reverse(initial_roads_ordering.begin()->bearing);
}();
// sort roads with respect to the initial bearings, a tie-breaker for equal initial bearings
// is to order roads via final bearings to have roads in clockwise order
//
// rhs <---. lhs <----.
// / /
// lhs / rhs /
//
// lhs road is before rhs one rhs road is before lhs one
// bearing::angleBetween < 180 bearing::angleBetween > 180
const auto initial_bearing_order = makeCompareShapeDataAngleToBearing(base_initial_bearing);
std::sort(initial_roads_ordering.begin(),
initial_roads_ordering.end(),
[&initial_bearing_order](const auto &lhs, const auto &rhs) {
return initial_bearing_order(lhs, rhs) ||
(lhs.bearing == rhs.bearing &&
util::bearing::angleBetween(lhs.road.bearing, rhs.road.bearing) <
180);
});
// copy intersection data in the initial order
IntersectionShape intersection;
intersection.reserve(initial_roads_ordering.size());
std::transform(initial_roads_ordering.begin(),
initial_roads_ordering.end(),
std::back_inserter(intersection),
[](const auto &entry) { return entry.road; });
if (intersection.size() > 2)
{ // Check bearings ordering with respect to true bearings
const auto base_bearing = intersection.front().bearing;
const auto bearings_order =
makeCompareShapeDataAngleToBearing(util::bearing::reverse(base_bearing));
for (auto curr = intersection.begin(), next = std::next(curr);
next != intersection.end();
++curr, ++next)
{
if (bearings_order(*next, *curr))
{ // If the true bearing is out of the initial order (next before current) then
// adjust the next bearing to keep the order. The adjustment angle is at most
// 0.5° or a half-angle between the current bearing and the base bearing.
// to prevent overlapping over base bearing + 360°.
const auto angle_adjustment = std::min(
.5, util::restrictAngleToValidRange(base_bearing - curr->bearing) / 2.);
next->bearing =
util::restrictAngleToValidRange(curr->bearing + angle_adjustment);
}
}
}
return intersection;
}
return IntersectionShape{};
}
// a
// |
// |
// v
// For an intersection from_node --via_eid--> turn_node ----> c
// ^
// |
// |
// b
// This functions returns _all_ turns as if the graph was undirected.
// That means we not only get (from_node, turn_node, c) in the above example
// but also (from_node, turn_node, a), (from_node, turn_node, b). These turns are
// marked as invalid and only needed for intersection classification.
IntersectionView IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
const EdgeID via_eid,
const bool use_low_precision_angles) const
{
// make sure the via-eid is valid
BOOST_ASSERT([this](const NodeID from_node, const EdgeID via_eid) {
const auto range = node_based_graph.GetAdjacentEdgeRange(from_node);
return range.front() <= via_eid && via_eid <= range.back();
}(from_node, via_eid));
auto intersection = ComputeIntersectionShape(
node_based_graph.GetTarget(via_eid), boost::none, use_low_precision_angles);
return TransformIntersectionShapeIntoView(from_node, via_eid, std::move(intersection));
}
IntersectionGenerationParameters
IntersectionGenerator::SkipDegreeTwoNodes(const NodeID starting_node, const EdgeID via_edge) const
{
@ -277,212 +80,6 @@ IntersectionGenerator::SkipDegreeTwoNodes(const NodeID starting_node, const Edge
return {query_node, query_edge};
}
IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView(
const NodeID previous_node,
const EdgeID entering_via_edge,
const IntersectionShape &intersection_shape) const
{
// requires a copy of the intersection
return TransformIntersectionShapeIntoView(previous_node,
entering_via_edge,
intersection_shape, // creates a copy
intersection_shape, // reference to local
{}); // empty vector of performed merges
}
IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView(
const NodeID previous_node,
const EdgeID entering_via_edge,
const IntersectionShape &normalized_intersection,
const IntersectionShape &intersection,
const std::vector<IntersectionNormalizationOperation> &performed_merges) const
{
const auto node_at_intersection = node_based_graph.GetTarget(entering_via_edge);
// request all turn restrictions
auto const restrictions = restriction_map.Restrictions(previous_node, node_at_intersection);
// check turn restrictions to find a node that is the only allowed target when coming from a
// node to an intersection
// d
// |
// a - b - c and `only_straight_on ab | bc would return `c` for `a,b`
const auto find_only_valid_turn = [&]() -> boost::optional<NodeID> {
const auto itr = std::find_if(restrictions.first, restrictions.second, [](auto pair) {
return pair.second->is_only;
});
if (itr != restrictions.second)
return itr->second->AsNodeRestriction().to;
else
return boost::none;
};
const auto only_valid_turn = find_only_valid_turn();
// barriers change our behaviour regarding u-turns
const bool is_barrier_node = barrier_nodes.find(node_at_intersection) != barrier_nodes.end();
const auto connect_to_previous_node = [this, previous_node](const IntersectionShapeData road) {
return node_based_graph.GetTarget(road.eid) == previous_node;
};
// check which of the edges is the u-turn edge
const auto uturn_edge_itr =
std::find_if(intersection.begin(), intersection.end(), connect_to_previous_node);
// there needs to be a connection, otherwise stuff went seriously wrong. Note that this is not
// necessarily the same id as `entering_via_edge`.
// In cases where parallel edges are present, we only remember the minimal edge. Both share
// exactly the same coordinates, so the u-turn is still the best choice here.
BOOST_ASSERT(uturn_edge_itr != intersection.end());
const auto is_restricted = [&](const NodeID destination) {
// check if we have a dedicated destination
if (only_valid_turn)
return *only_valid_turn != destination;
// check if explicitly forbidden
return restrictions.second !=
std::find_if(restrictions.first, restrictions.second, [&](const auto &restriction) {
return restriction.second->AsNodeRestriction().to == destination;
});
};
const auto is_allowed_turn = [&](const IntersectionShapeData &road) {
const auto &road_data = node_based_graph.GetEdgeData(road.eid);
const NodeID road_destination_node = node_based_graph.GetTarget(road.eid);
// reverse edges are never valid turns because the resulting turn would look like this:
// from_node --via_edge--> node_at_intersection <--onto_edge-- to_node
// however we need this for capture intersection shape for incoming one-ways
return !road_data.reversed &&
// we are not turning over a barrier
(!is_barrier_node || road_destination_node == previous_node) &&
// don't allow restricted turns
!is_restricted(road_destination_node);
};
// due to merging of roads, the u-turn might actually not be part of the intersection anymore
// uturn is a pair of {edge id, bearing}
const auto uturn = [&]() {
const auto merge_entry = std::find_if(
performed_merges.begin(), performed_merges.end(), [&uturn_edge_itr](const auto entry) {
return entry.merged_eid == uturn_edge_itr->eid;
});
if (merge_entry != performed_merges.end())
{
const auto merged_into_id = merge_entry->into_eid;
const auto merged_u_turn = std::find_if(
normalized_intersection.begin(),
normalized_intersection.end(),
[&](const IntersectionShapeData &road) { return road.eid == merged_into_id; });
BOOST_ASSERT(merged_u_turn != normalized_intersection.end());
return std::make_pair(merged_u_turn->eid,
util::bearing::reverse(merged_u_turn->bearing));
}
else
{
const auto uturn_edge_at_normalized_intersection_itr =
std::find_if(normalized_intersection.begin(),
normalized_intersection.end(),
connect_to_previous_node);
BOOST_ASSERT(uturn_edge_at_normalized_intersection_itr !=
normalized_intersection.end());
return std::make_pair(
uturn_edge_at_normalized_intersection_itr->eid,
util::bearing::reverse(uturn_edge_at_normalized_intersection_itr->bearing));
}
}();
IntersectionView intersection_view;
intersection_view.reserve(normalized_intersection.size());
std::transform(normalized_intersection.begin(),
normalized_intersection.end(),
std::back_inserter(intersection_view),
[&](const IntersectionShapeData &road) {
return IntersectionViewData(
road,
is_allowed_turn(road),
util::bearing::angleBetween(uturn.second, road.bearing));
});
const auto uturn_edge_at_intersection_view_itr =
std::find_if(intersection_view.begin(), intersection_view.end(), connect_to_previous_node);
// number of found valid exit roads
const auto valid_count =
std::count_if(intersection_view.begin(),
intersection_view.end(),
[](const IntersectionViewData &road) { return road.entry_allowed; });
// in general, we don't wan't to allow u-turns. If we don't look at a barrier, we have to check
// for dead end streets. These are the only ones that we allow uturns for, next to barriers
// (which are also kind of a dead end, but we don't have to check these again :))
if (uturn_edge_at_intersection_view_itr != intersection_view.end() &&
((uturn_edge_at_intersection_view_itr->entry_allowed && !is_barrier_node &&
valid_count != 1) ||
valid_count == 0))
{
const auto allow_uturn_at_dead_end = [&]() {
const auto &uturn_data = node_based_graph.GetEdgeData(uturn_edge_itr->eid);
// we can't turn back onto oneway streets
if (uturn_data.reversed)
return false;
// don't allow explicitly restricted turns
if (is_restricted(previous_node))
return false;
// we define dead ends as roads that can only be entered via the possible u-turn
const auto is_bidirectional = [&](const EdgeID entering_via_edge) {
const auto to_node = node_based_graph.GetTarget(entering_via_edge);
const auto reverse_edge = node_based_graph.FindEdge(to_node, node_at_intersection);
BOOST_ASSERT(reverse_edge != SPECIAL_EDGEID);
return !node_based_graph.GetEdgeData(reverse_edge).reversed;
};
const auto bidirectional_edges = [&]() {
std::uint32_t count = 0;
for (const auto eid : node_based_graph.GetAdjacentEdgeRange(node_at_intersection))
if (is_bidirectional(eid))
++count;
return count;
}();
// Checking for dead-end streets is kind of difficult. There is obvious dead ends
// (single road connected)
return bidirectional_edges <= 1;
}();
uturn_edge_at_intersection_view_itr->entry_allowed = allow_uturn_at_dead_end;
}
std::sort(std::begin(intersection_view),
std::end(intersection_view),
std::mem_fn(&IntersectionViewData::CompareByAngle));
// Move entering_via_edge to intersection front and place all roads prior entering_via_edge
// at the end of the intersection view with 360° angle
auto entering_via_it = std::find_if(intersection_view.begin(),
intersection_view.end(),
[&uturn](auto &road) { return road.eid == uturn.first; });
OSRM_ASSERT(entering_via_it != intersection_view.end() && entering_via_it->angle >= 0. &&
entering_via_it->angle < std::numeric_limits<double>::epsilon(),
coordinates[node_at_intersection]);
if (entering_via_it != intersection_view.begin() && entering_via_it != intersection_view.end())
{
std::for_each(
intersection_view.begin(), entering_via_it, [](auto &road) { road.angle = 360.; });
std::rotate(intersection_view.begin(), entering_via_it, intersection_view.end());
}
return intersection_view;
}
const CoordinateExtractor &IntersectionGenerator::GetCoordinateExtractor() const
{
return coordinate_extractor;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm

View File

@ -1,5 +1,6 @@
#include "extractor/guidance/intersection_handler.hpp"
#include "extractor/guidance/constants.hpp"
#include "extractor/intersection/intersection_analysis.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/guidance/name_announcements.hpp"
@ -45,17 +46,29 @@ inline bool requiresAnnouncement(const util::NodeBasedDynamicGraph &node_based_g
}
} // namespace detail
IntersectionHandler::IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator)
IntersectionHandler::IntersectionHandler(
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator)
: node_based_graph(node_based_graph), node_data_container(node_data_container),
coordinates(coordinates), name_table(name_table),
node_coordinates(node_coordinates), compressed_geometries(compressed_geometries),
node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes),
turn_lanes_data(turn_lanes_data), name_table(name_table),
street_name_suffix_table(street_name_suffix_table),
intersection_generator(intersection_generator),
graph_walker(node_based_graph, node_data_container, intersection_generator)
intersection_generator(intersection_generator), graph_walker(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data)
{
}
@ -162,8 +175,8 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
// or actually follow the full road. When 2399 lands, we can exchange here for a
// precalculated distance value.
const auto distance = util::coordinate_calculation::haversineDistance(
coordinates[node_based_graph.GetTarget(via_edge)],
coordinates[node_based_graph.GetTarget(road.eid)]);
node_coordinates[node_based_graph.GetTarget(via_edge)],
node_coordinates[node_based_graph.GetTarget(road.eid)]);
return {TurnType::Turn,
(angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
@ -470,8 +483,15 @@ IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) cons
return boost::none;
}
auto intersection =
intersection_generator(intersection_parameters.nid, intersection_parameters.via_eid);
auto intersection = intersection::getConnectedRoads(
node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{intersection_parameters.nid, intersection_parameters.via_eid});
auto intersection_node = node_based_graph.GetTarget(intersection_parameters.via_eid);
if (intersection.size() <= 2 || intersection.isTrafficSignalOrBarrier())

View File

@ -3,6 +3,7 @@
#include "extractor/guidance/coordinate_extractor.hpp"
#include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/node_based_graph_walker.hpp"
#include "extractor/intersection/intersection_analysis.hpp"
#include "extractor/query_node.hpp"
#include "extractor/suffix_table.hpp"
@ -52,15 +53,22 @@ inline auto makeCheckRoadForName(const NameID name_id,
}
}
MergableRoadDetector::MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const IntersectionGenerator &intersection_generator,
const CoordinateExtractor &coordinate_extractor,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
MergableRoadDetector::MergableRoadDetector(
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const IntersectionGenerator &intersection_generator,
const CoordinateExtractor &coordinate_extractor,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
: node_based_graph(node_based_graph), node_data_container(node_data_container),
node_coordinates(node_coordinates), intersection_generator(intersection_generator),
node_coordinates(node_coordinates), compressed_geometries(compressed_geometries),
node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes),
turn_lanes_data(turn_lanes_data), intersection_generator(intersection_generator),
coordinate_extractor(coordinate_extractor), name_table(name_table),
street_name_suffix_table(street_name_suffix_table)
{
@ -180,8 +188,22 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
{
// selection data to the right and left
const auto constexpr SMALL_RANDOM_HOPLIMIT = 5;
IntersectionFinderAccumulator left_accumulator(SMALL_RANDOM_HOPLIMIT, intersection_generator),
right_accumulator(SMALL_RANDOM_HOPLIMIT, intersection_generator);
IntersectionFinderAccumulator left_accumulator(SMALL_RANDOM_HOPLIMIT,
node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data),
right_accumulator(SMALL_RANDOM_HOPLIMIT,
node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data);
/* Standard following the straightmost road
* Since both items have the same id, we can `select` based on any setup
@ -193,8 +215,13 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
/*requires entry=*/false,
false);
NodeBasedGraphWalker graph_walker(
node_based_graph, node_data_container, intersection_generator);
NodeBasedGraphWalker graph_walker(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data);
graph_walker.TraverseRoad(intersection_node, lhs.eid, left_accumulator, selector);
/* if the intersection does not have a right turn, we continue onto the next one once
* (skipping over a single small side street)
@ -266,7 +293,13 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
// check if both intersections are connected
IntersectionFinderAccumulator connect_accumulator(SMALL_RANDOM_HOPLIMIT,
intersection_generator);
node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data);
graph_walker.TraverseRoad(node_based_graph.GetTarget(left_accumulator.via_edge_id),
connector_turn->eid,
connect_accumulator,
@ -281,8 +314,13 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node,
const MergableRoadData &lhs,
const MergableRoadData &rhs) const
{
NodeBasedGraphWalker graph_walker(
node_based_graph, node_data_container, intersection_generator);
NodeBasedGraphWalker graph_walker(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data);
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) {
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
SelectStraightmostRoadByNameAndOnlyChoice selector(
@ -348,8 +386,13 @@ bool MergableRoadDetector::HaveSameDirection(const NodeID intersection_node,
return false;
// Find a coordinate following a road that is far away
NodeBasedGraphWalker graph_walker(
node_based_graph, node_data_container, intersection_generator);
NodeBasedGraphWalker graph_walker(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data);
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) {
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
SelectStraightmostRoadByNameAndOnlyChoice selector(
@ -517,8 +560,15 @@ bool MergableRoadDetector::IsLinkRoad(const NodeID intersection_node,
{
const auto next_intersection_parameters =
intersection_generator.SkipDegreeTwoNodes(intersection_node, road.eid);
const auto next_intersection_along_road = intersection_generator.GetConnectedRoads(
next_intersection_parameters.nid, next_intersection_parameters.via_eid);
const auto next_intersection_along_road = intersection::getConnectedRoads(
node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{next_intersection_parameters.nid, next_intersection_parameters.via_eid});
const auto extract_name_id = [this](const MergableRoadData &road) {
return node_data_container
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)

View File

@ -42,12 +42,20 @@ inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_base
MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator)
: IntersectionHandler(node_based_graph,
node_data_container,
coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator)

View File

@ -1,4 +1,5 @@
#include "extractor/guidance/node_based_graph_walker.hpp"
#include "extractor/intersection/intersection_analysis.hpp"
#include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp"
@ -14,11 +15,18 @@ namespace guidance
{
// ---------------------------------------------------------------------------------
NodeBasedGraphWalker::NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const IntersectionGenerator &intersection_generator)
NodeBasedGraphWalker::NodeBasedGraphWalker(
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data)
: node_based_graph(node_based_graph), node_data_container(node_data_container),
intersection_generator(intersection_generator)
node_coordinates(node_coordinates), compressed_geometries(compressed_geometries),
node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes),
turn_lanes_data(turn_lanes_data)
{
}
@ -235,8 +243,18 @@ operator()(const NodeID /*nid*/,
// ---------------------------------------------------------------------------------
IntersectionFinderAccumulator::IntersectionFinderAccumulator(
const std::uint8_t hop_limit, const IntersectionGenerator &intersection_generator)
: hops(0), hop_limit(hop_limit), intersection_generator(intersection_generator)
const std::uint8_t hop_limit,
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data)
: hops(0), hop_limit(hop_limit), node_based_graph(node_based_graph),
node_data_container(node_data_container), node_coordinates(node_coordinates),
compressed_geometries(compressed_geometries), node_restriction_map(node_restriction_map),
barrier_nodes(barrier_nodes), turn_lanes_data(turn_lanes_data)
{
}
@ -261,7 +279,14 @@ void IntersectionFinderAccumulator::update(const NodeID from_node,
nid = from_node;
via_edge_id = via_edge;
intersection = intersection_generator.GetConnectedRoads(from_node, via_edge, true);
intersection = intersection::getConnectedRoads(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{from_node, via_edge});
}
} // namespace guidance

View File

@ -23,21 +23,28 @@ namespace extractor
namespace guidance
{
RoundaboutHandler::RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const CompressedEdgeContainer &compressed_edge_container,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator)
RoundaboutHandler::RoundaboutHandler(
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator)
: IntersectionHandler(node_based_graph,
node_data_container,
coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator),
compressed_edge_container(compressed_edge_container),
coordinate_extractor(node_based_graph, compressed_edge_container, coordinates)
coordinate_extractor(node_based_graph, compressed_geometries, coordinates)
{
}
@ -143,7 +150,7 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
continue;
// there is a single non-roundabout edge
const auto src_coordinate = coordinates[node];
const auto src_coordinate = node_coordinates[node];
const auto edge_range = node_based_graph.GetAdjacentEdgeRange(node);
const auto number_of_lanes_at_intersection = std::accumulate(
@ -262,11 +269,11 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
const auto getEdgeLength = [&](const NodeID source_node, EdgeID eid) {
double length = 0.;
auto last_coord = coordinates[source_node];
const auto &edge_bucket = compressed_edge_container.GetBucketReference(eid);
auto last_coord = node_coordinates[source_node];
const auto &edge_bucket = compressed_geometries.GetBucketReference(eid);
for (const auto &compressed_edge : edge_bucket)
{
const auto next_coord = coordinates[compressed_edge.node_id];
const auto next_coord = node_coordinates[compressed_edge.node_id];
length += util::coordinate_calculation::haversineDistance(last_coord, next_coord);
last_coord = next_coord;
}

View File

@ -25,15 +25,24 @@ namespace guidance
SliproadHandler::SliproadHandler(const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
: IntersectionHandler(node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator)
intersection_generator),
coordinate_extractor(node_based_graph, compressed_geometries, node_coordinates)
{
}
@ -243,7 +252,14 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
// Starting out at the intersection and going onto the Sliproad we skip artificial
// degree two intersections and limit the max hop count in doing so.
IntersectionFinderAccumulator intersection_finder{10, intersection_generator};
IntersectionFinderAccumulator intersection_finder{10,
node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data};
const SkipTrafficSignalBarrierRoadSelector road_selector{};
(void)graph_walker.TraverseRoad(intersection_node_id, // start node
sliproad_edge, // onto edge
@ -372,8 +388,6 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
//
// Sliproad Not a Sliproad
{
const auto &coordinate_extractor = intersection_generator.GetCoordinateExtractor();
const NodeID start = intersection_node_id; // b
const EdgeID edge = sliproad_edge; // bd
@ -424,8 +438,8 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
// Only check for curvature and ~90 degree when it makes sense to do so.
const constexpr auto MIN_LENGTH = 3.;
const auto length = haversineDistance(coordinates[intersection_node_id],
coordinates[main_road_intersection->node]);
const auto length = haversineDistance(node_coordinates[intersection_node_id],
node_coordinates[main_road_intersection->node]);
const double minimal_crossroad_angle_of_intersection = 40.;
@ -546,8 +560,15 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
}
else
{
const auto skip_traffic_light_intersection = intersection_generator(
node_based_graph.GetTarget(sliproad_edge), candidate_road.eid);
const auto skip_traffic_light_intersection = intersection::getConnectedRoads(
node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{node_based_graph.GetTarget(sliproad_edge), candidate_road.eid});
if (skip_traffic_light_intersection.isTrafficSignalOrBarrier() &&
node_based_graph.GetTarget(skip_traffic_light_intersection[1].eid) ==
main_road_intersection->node)
@ -656,8 +677,6 @@ bool SliproadHandler::nextIntersectionIsTooFarAway(const NodeID start, const Edg
BOOST_ASSERT(start != SPECIAL_NODEID);
BOOST_ASSERT(onto != SPECIAL_EDGEID);
const auto &coordinate_extractor = intersection_generator.GetCoordinateExtractor();
// Base max distance threshold on the current road class we're on
const auto &data = node_based_graph.GetEdgeData(onto).flags;
const auto threshold = scaledThresholdByRoadClass(MAX_SLIPROAD_THRESHOLD, // <- scales down
@ -728,9 +747,9 @@ bool SliproadHandler::isValidSliproadArea(const double max_area,
{
using namespace util::coordinate_calculation;
const auto first = coordinates[a];
const auto second = coordinates[b];
const auto third = coordinates[c];
const auto first = node_coordinates[a];
const auto second = node_coordinates[b];
const auto third = node_coordinates[c];
const auto length = haversineDistance(first, second);
const auto heigth = haversineDistance(second, third);

View File

@ -11,15 +11,24 @@ namespace extractor
namespace guidance
{
SuppressModeHandler::SuppressModeHandler(const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
SuppressModeHandler::SuppressModeHandler(
const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
: IntersectionHandler(node_based_graph,
node_data_container,
coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator)

View File

@ -23,60 +23,87 @@ using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const std::vector<util::Coordinate> &node_coordinates,
const CompressedEdgeContainer &compressed_edge_container,
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const CompressedEdgeContainer &compressed_edge_container,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
: node_based_graph(node_based_graph), intersection_generator(node_based_graph,
node_data_container,
restriction_map,
barrier_nodes,
coordinates,
node_coordinates,
compressed_edge_container),
roundabout_handler(node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_edge_container,
restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator),
motorway_handler(node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_edge_container,
restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator),
turn_handler(node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_edge_container,
restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator),
sliproad_handler(intersection_generator,
node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_edge_container,
restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table),
suppress_mode_handler(intersection_generator,
node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_edge_container,
restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table),
driveway_handler(intersection_generator,
node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_edge_container,
restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table),
statistics_handler(intersection_generator,
node_based_graph,
node_data_container,
coordinates,
node_coordinates,
compressed_edge_container,
restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table)
{
@ -188,11 +215,6 @@ Intersection TurnAnalysis::setTurnTypes(const NodeID node_prior_to_intersection,
return intersection;
}
const IntersectionGenerator &TurnAnalysis::GetIntersectionGenerator() const
{
return intersection_generator;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm

View File

@ -1,5 +1,6 @@
#include "extractor/guidance/turn_discovery.hpp"
#include "extractor/guidance/constants.hpp"
#include "extractor/intersection/intersection_analysis.hpp"
#include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp"
@ -14,16 +15,16 @@ namespace guidance
namespace lanes
{
namespace
{
const constexpr bool USE_LOW_PRECISION_MODE = true;
}
bool findPreviousIntersection(const NodeID node_v,
const EdgeID via_edge,
const Intersection &intersection,
const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
// output parameters
NodeID &result_node,
EdgeID &result_via_edge,
@ -43,7 +44,9 @@ bool findPreviousIntersection(const NodeID node_v,
*/
const constexpr double COMBINE_DISTANCE_CUTOFF = 30;
const auto coordinate_extractor = intersection_generator.GetCoordinateExtractor();
const CoordinateExtractor coordinate_extractor(
node_based_graph, compressed_geometries, node_coordinates);
const auto coordinates_along_via_edge =
coordinate_extractor.GetForwardCoordinatesAlongRoad(node_v, via_edge);
const auto via_edge_length =
@ -71,7 +74,14 @@ bool findPreviousIntersection(const NodeID node_v,
return false;
const auto node_v_reverse_intersection =
intersection_generator.GetConnectedRoads(node_w, u_turn_at_node_w, USE_LOW_PRECISION_MODE);
intersection::getConnectedRoads(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{node_w, u_turn_at_node_w});
// Continue along the straightmost turn. If there is no straight turn, we cannot find a valid
// previous intersection.
const auto straightmost_at_v_in_reverse =
@ -83,8 +93,15 @@ bool findPreviousIntersection(const NodeID node_v,
return false;
const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid);
const auto node_u_reverse_intersection = intersection_generator.GetConnectedRoads(
node_v, straightmost_at_v_in_reverse->eid, USE_LOW_PRECISION_MODE);
const auto node_u_reverse_intersection =
intersection::getConnectedRoads(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{node_v, straightmost_at_v_in_reverse->eid});
// now check that the u-turn at the given intersection connects to via-edge
// The u-turn at the now found intersection should, hopefully, represent the previous edge.
@ -102,7 +119,14 @@ bool findPreviousIntersection(const NodeID node_v,
return false;
}
result_intersection = intersection_generator(node_u, result_via_edge);
result_intersection = intersection::getConnectedRoads(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{node_u, result_via_edge});
const auto check_via_edge =
result_intersection.end() !=
std::find_if(result_intersection.begin(),

View File

@ -113,12 +113,20 @@ std::size_t TurnHandler::Fork::getLeftIndex() const
TurnHandler::TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const IntersectionGenerator &intersection_generator)
: IntersectionHandler(node_based_graph,
node_data_container,
coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
name_table,
street_name_suffix_table,
intersection_generator)

View File

@ -3,6 +3,7 @@
#include "extractor/guidance/turn_discovery.hpp"
#include "extractor/guidance/turn_lane_augmentation.hpp"
#include "extractor/guidance/turn_lane_matcher.hpp"
#include "extractor/intersection/intersection_analysis.hpp"
#include "util/bearing.hpp"
#include "util/log.hpp"
#include "util/typedefs.hpp"
@ -35,14 +36,21 @@ std::size_t getNumberOfTurns(const Intersection &intersection)
TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
LaneDescriptionMap &lane_description_map,
const TurnAnalysis &turn_analysis,
util::guidance::LaneDataIdMap &id_map)
: node_based_graph(node_based_graph), node_data_container(node_data_container),
lane_description_map(lane_description_map), turn_analysis(turn_analysis), id_map(id_map)
node_coordinates(node_coordinates), compressed_geometries(compressed_geometries),
node_restriction_map(node_restriction_map), barrier_nodes(barrier_nodes),
turn_lanes_data(turn_lanes_data), lane_description_map(lane_description_map),
turn_analysis(turn_analysis), id_map(id_map)
{
std::tie(turn_lane_offsets, turn_lane_masks) =
transformTurnLaneMapIntoArrays(lane_description_map);
std::tie(turn_lane_offsets, turn_lane_masks) = turn_lanes_data;
count_handled = count_called = 0;
}
@ -205,8 +213,13 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at,
if (findPreviousIntersection(at,
via_edge,
intersection,
turn_analysis.GetIntersectionGenerator(),
node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
previous_node,
previous_via_edge,
previous_intersection_view))
@ -559,8 +572,17 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
// find out about the next intersection. To check for valid matches, we also need the turn
// types. We can skip merging/angle adjustments, though
const auto next_intersection = turn_analysis.AssignTurnTypes(
at, straightmost->eid, turn_analysis.GetIntersectionGenerator()(at, straightmost->eid));
const auto next_intersection =
turn_analysis.AssignTurnTypes(at,
straightmost->eid,
intersection::getConnectedRoads(node_based_graph,
node_data_container,
node_coordinates,
compressed_geometries,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
{at, straightmost->eid}));
// check where we can match turn lanes
std::size_t straightmost_tag_index = turn_lane_data.size();

View File

@ -658,7 +658,7 @@ bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph,
return true;
}
// TODO: the function adapts intersection geometry data to TurnAnalysis
// The function adapts intersection geometry data to TurnAnalysis
guidance::IntersectionView
convertToIntersectionView(const util::NodeBasedDynamicGraph &graph,
const EdgeBasedNodeDataContainer &node_data_container,
@ -727,6 +727,62 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph,
return intersection_view;
}
// a
// |
// |
// v
// For an intersection from_node --via_eid--> turn_node ----> c
// ^
// |
// |
// b
// This functions returns _all_ turns as if the graph was undirected.
// That means we not only get (from_node, turn_node, c) in the above example
// but also (from_node, turn_node, a), (from_node, turn_node, b). These turns are
// marked as invalid and only needed for intersection classification.
guidance::IntersectionView
getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
const EdgeBasedNodeDataContainer &node_data_container,
const std::vector<util::Coordinate> &node_coordinates,
const extractor::CompressedEdgeContainer &compressed_geometries,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const guidance::TurnLanesIndexedArray &turn_lanes_data,
const IntersectionEdge &incoming_edge)
{
const auto intersection_node = graph.GetTarget(incoming_edge.edge);
const auto &outgoing_edges = intersection::getOutgoingEdges(graph, intersection_node);
auto edge_geometries = getIntersectionOutgoingGeometries(
graph, compressed_geometries, node_coordinates, intersection_node);
// Add incoming edges with reversed bearings
const auto edges_number = edge_geometries.size();
edge_geometries.resize(2 * edges_number);
for (std::size_t index = 0; index < edges_number; ++index)
{
const auto &geometry = edge_geometries[index];
const auto remote_node = graph.GetTarget(geometry.edge);
const auto incoming_edge = graph.FindEdge(remote_node, intersection_node);
edge_geometries[edges_number + index] = {incoming_edge,
util::bearing::reverse(geometry.initial_bearing),
util::bearing::reverse(geometry.perceived_bearing),
geometry.length};
}
// Enforce ordering of edges by IDs
std::sort(edge_geometries.begin(), edge_geometries.end());
return convertToIntersectionView(graph,
node_data_container,
node_restriction_map,
barrier_nodes,
edge_geometries,
turn_lanes_data,
incoming_edge,
outgoing_edges,
std::unordered_set<EdgeID>());
}
}
}
}