Remove GetConnectedRoads from IntersectionGenerator
This commit is contained in:
parent
cc1a5ea78d
commit
db7c76d04d
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user