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 util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_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)
|
inline auto makeCompareAngularDeviation(const double angle)
|
||||||
{
|
{
|
||||||
return [angle](const auto &lhs, const auto &rhs) {
|
return [angle](const auto &lhs, const auto &rhs) {
|
||||||
|
@ -44,26 +44,6 @@ class IntersectionGenerator
|
|||||||
const std::vector<util::Coordinate> &coordinates,
|
const std::vector<util::Coordinate> &coordinates,
|
||||||
const CompressedEdgeContainer &compressed_edge_container);
|
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
|
// 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
|
// 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
|
// 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,
|
IntersectionGenerationParameters SkipDegreeTwoNodes(const NodeID starting_node,
|
||||||
const EdgeID via_edge) const;
|
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:
|
private:
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
const EdgeBasedNodeDataContainer &node_data_container;
|
const EdgeBasedNodeDataContainer &node_data_container;
|
||||||
const RestrictionMap &restriction_map;
|
const RestrictionMap &restriction_map;
|
||||||
const std::unordered_set<NodeID> &barrier_nodes;
|
const std::unordered_set<NodeID> &barrier_nodes;
|
||||||
const std::vector<util::Coordinate> &coordinates;
|
const std::vector<util::Coordinate> &coordinates;
|
||||||
|
|
||||||
// own state, used to find the correct coordinates along a road
|
|
||||||
const CoordinateExtractor coordinate_extractor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "extractor/guidance/intersection.hpp"
|
#include "extractor/guidance/intersection.hpp"
|
||||||
#include "extractor/guidance/intersection_generator.hpp"
|
#include "extractor/guidance/intersection_generator.hpp"
|
||||||
#include "extractor/guidance/node_based_graph_walker.hpp"
|
#include "extractor/guidance/node_based_graph_walker.hpp"
|
||||||
|
#include "extractor/intersection/intersection_analysis.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
#include "extractor/suffix_table.hpp"
|
#include "extractor/suffix_table.hpp"
|
||||||
|
|
||||||
@ -34,7 +35,11 @@ class IntersectionHandler
|
|||||||
public:
|
public:
|
||||||
IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table,
|
const SuffixTable &street_name_suffix_table,
|
||||||
const IntersectionGenerator &intersection_generator);
|
const IntersectionGenerator &intersection_generator);
|
||||||
@ -52,7 +57,11 @@ class IntersectionHandler
|
|||||||
protected:
|
protected:
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
const EdgeBasedNodeDataContainer &node_data_container;
|
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 util::NameTable &name_table;
|
||||||
const SuffixTable &street_name_suffix_table;
|
const SuffixTable &street_name_suffix_table;
|
||||||
const IntersectionGenerator &intersection_generator;
|
const IntersectionGenerator &intersection_generator;
|
||||||
@ -571,7 +580,15 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
node_at_intersection, intersection[0].eid);
|
node_at_intersection, intersection[0].eid);
|
||||||
if (node_based_graph.GetTarget(parameters.via_eid) == node_at_intersection)
|
if (node_based_graph.GetTarget(parameters.via_eid) == node_at_intersection)
|
||||||
return {};
|
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())
|
if (!previous_intersection.empty())
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS
|
#ifndef OSRM_EXTRACTOR_GUIDANCE_MERGEABLE_ROADS
|
||||||
#define 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/intersection.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_types.hpp"
|
||||||
|
#include "extractor/restriction_index.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
@ -9,6 +12,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
@ -39,6 +43,10 @@ class MergableRoadDetector
|
|||||||
MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph,
|
MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &node_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 IntersectionGenerator &intersection_generator,
|
const IntersectionGenerator &intersection_generator,
|
||||||
const CoordinateExtractor &coordinate_extractor,
|
const CoordinateExtractor &coordinate_extractor,
|
||||||
const util::NameTable &name_table,
|
const util::NameTable &name_table,
|
||||||
@ -159,6 +167,10 @@ class MergableRoadDetector
|
|||||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
const EdgeBasedNodeDataContainer &node_data_container;
|
const EdgeBasedNodeDataContainer &node_data_container;
|
||||||
const std::vector<util::Coordinate> &node_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 IntersectionGenerator &intersection_generator;
|
const IntersectionGenerator &intersection_generator;
|
||||||
const CoordinateExtractor &coordinate_extractor;
|
const CoordinateExtractor &coordinate_extractor;
|
||||||
|
|
||||||
|
@ -26,6 +26,10 @@ class MotorwayHandler : public IntersectionHandler
|
|||||||
MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table,
|
const SuffixTable &street_name_suffix_table,
|
||||||
const IntersectionGenerator &intersection_generator);
|
const IntersectionGenerator &intersection_generator);
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
#define OSRM_EXTRACTOR_GUIDANCE_NODE_BASED_GRAPH_WALKER
|
#define OSRM_EXTRACTOR_GUIDANCE_NODE_BASED_GRAPH_WALKER
|
||||||
|
|
||||||
#include "extractor/guidance/constants.hpp"
|
#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.hpp"
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
@ -29,7 +31,11 @@ class NodeBasedGraphWalker
|
|||||||
public:
|
public:
|
||||||
NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph,
|
NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
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
|
* the returned node-id, edge-id are either the last ones used, just prior accumulator
|
||||||
@ -48,7 +54,11 @@ class NodeBasedGraphWalker
|
|||||||
private:
|
private:
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
const EdgeBasedNodeDataContainer &node_data_container;
|
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
|
struct IntersectionFinderAccumulator
|
||||||
{
|
{
|
||||||
IntersectionFinderAccumulator(const std::uint8_t hop_limit,
|
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
|
// true if the path has traversed enough distance
|
||||||
bool terminate();
|
bool terminate();
|
||||||
|
|
||||||
@ -159,13 +175,19 @@ struct IntersectionFinderAccumulator
|
|||||||
std::uint8_t hops;
|
std::uint8_t hops;
|
||||||
const std::uint8_t hop_limit;
|
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
|
// the result we are looking for
|
||||||
NodeID nid;
|
NodeID nid;
|
||||||
EdgeID via_edge_id;
|
EdgeID via_edge_id;
|
||||||
IntersectionView intersection;
|
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>
|
template <class accumulator_type, class selector_type>
|
||||||
@ -199,9 +221,15 @@ NodeBasedGraphWalker::TraverseRoad(NodeID current_node_id,
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
// look at the next intersection
|
// look at the next intersection
|
||||||
const constexpr auto LOW_PRECISION = true;
|
const auto next_intersection =
|
||||||
const auto next_intersection = intersection_generator.GetConnectedRoads(
|
intersection::getConnectedRoads(node_based_graph,
|
||||||
current_node_id, current_edge_id, LOW_PRECISION);
|
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
|
// don't follow u-turns or go past our initial intersection
|
||||||
if (next_intersection.size() <= 1)
|
if (next_intersection.size() <= 1)
|
||||||
|
@ -42,7 +42,10 @@ class RoundaboutHandler : public IntersectionHandler
|
|||||||
RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table,
|
const SuffixTable &street_name_suffix_table,
|
||||||
const IntersectionGenerator &intersection_generator);
|
const IntersectionGenerator &intersection_generator);
|
||||||
@ -80,7 +83,6 @@ class RoundaboutHandler : public IntersectionHandler
|
|||||||
bool
|
bool
|
||||||
qualifiesAsRoundaboutIntersection(const std::unordered_set<NodeID> &roundabout_nodes) const;
|
qualifiesAsRoundaboutIntersection(const std::unordered_set<NodeID> &roundabout_nodes) const;
|
||||||
|
|
||||||
const CompressedEdgeContainer &compressed_edge_container;
|
|
||||||
const CoordinateExtractor coordinate_extractor;
|
const CoordinateExtractor coordinate_extractor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +28,10 @@ class SliproadHandler final : public IntersectionHandler
|
|||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_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`.
|
// The return value is guaranteed to not be larger than `threshold`.
|
||||||
static double scaledThresholdByRoadClass(const double max_threshold,
|
static double scaledThresholdByRoadClass(const double max_threshold,
|
||||||
const RoadClassification &classification);
|
const RoadClassification &classification);
|
||||||
|
|
||||||
|
const CoordinateExtractor coordinate_extractor;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
|
@ -31,11 +31,19 @@ class StatisticsHandler final : public IntersectionHandler
|
|||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table)
|
const SuffixTable &street_name_suffix_table)
|
||||||
: IntersectionHandler(node_based_graph,
|
: IntersectionHandler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
coordinates,
|
||||||
|
compressed_geometries,
|
||||||
|
node_restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator)
|
intersection_generator)
|
||||||
|
@ -25,6 +25,10 @@ class SuppressModeHandler final : public IntersectionHandler
|
|||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table);
|
const SuffixTable &street_name_suffix_table);
|
||||||
|
|
||||||
|
@ -42,10 +42,11 @@ class TurnAnalysis
|
|||||||
public:
|
public:
|
||||||
TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
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 RestrictionMap &restriction_map,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
const guidance::TurnLanesIndexedArray &turn_lanes_data,
|
||||||
const util::NameTable &name_table,
|
const util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table);
|
const SuffixTable &street_name_suffix_table);
|
||||||
|
|
||||||
@ -61,8 +62,6 @@ class TurnAnalysis
|
|||||||
const EdgeID via_eid,
|
const EdgeID via_eid,
|
||||||
const IntersectionView &intersection) const;
|
const IntersectionView &intersection) const;
|
||||||
|
|
||||||
const IntersectionGenerator &GetIntersectionGenerator() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
const IntersectionGenerator intersection_generator;
|
const IntersectionGenerator intersection_generator;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "extractor/guidance/intersection.hpp"
|
#include "extractor/guidance/intersection.hpp"
|
||||||
#include "extractor/guidance/intersection_generator.hpp"
|
#include "extractor/guidance/intersection_generator.hpp"
|
||||||
|
#include "extractor/guidance/turn_lane_data.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
@ -21,8 +22,13 @@ bool findPreviousIntersection(
|
|||||||
const NodeID node,
|
const NodeID node,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const Intersection &intersection,
|
const Intersection &intersection,
|
||||||
const IntersectionGenerator &intersection_generator,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph, // query edge data
|
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
|
// output parameters, will be in an arbitrary state on failure
|
||||||
NodeID &result_node,
|
NodeID &result_node,
|
||||||
EdgeID &result_via_edge,
|
EdgeID &result_via_edge,
|
||||||
|
@ -30,6 +30,10 @@ class TurnHandler : public IntersectionHandler
|
|||||||
TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table,
|
const SuffixTable &street_name_suffix_table,
|
||||||
const IntersectionGenerator &intersection_generator);
|
const IntersectionGenerator &intersection_generator);
|
||||||
|
@ -74,6 +74,11 @@ class TurnLaneHandler
|
|||||||
|
|
||||||
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
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,
|
LaneDescriptionMap &lane_description_map,
|
||||||
const TurnAnalysis &turn_analysis,
|
const TurnAnalysis &turn_analysis,
|
||||||
util::guidance::LaneDataIdMap &id_map);
|
util::guidance::LaneDataIdMap &id_map);
|
||||||
@ -90,6 +95,12 @@ class TurnLaneHandler
|
|||||||
// lanes for a turn
|
// lanes for a turn
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
const EdgeBasedNodeDataContainer &node_data_container;
|
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<std::uint32_t> turn_lane_offsets;
|
||||||
std::vector<TurnLaneType::Mask> turn_lane_masks;
|
std::vector<TurnLaneType::Mask> turn_lane_masks;
|
||||||
LaneDescriptionMap &lane_description_map;
|
LaneDescriptionMap &lane_description_map;
|
||||||
|
@ -26,6 +26,19 @@ IntersectionEdges getIncomingEdges(const util::NodeBasedDynamicGraph &graph,
|
|||||||
IntersectionEdges getOutgoingEdges(const util::NodeBasedDynamicGraph &graph,
|
IntersectionEdges getOutgoingEdges(const util::NodeBasedDynamicGraph &graph,
|
||||||
const NodeID intersection);
|
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>>
|
std::pair<IntersectionEdgeGeometries, std::unordered_set<EdgeID>>
|
||||||
getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
|
getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
|
||||||
const extractor::CompressedEdgeContainer &compressed_geometries,
|
const extractor::CompressedEdgeContainer &compressed_geometries,
|
||||||
@ -44,18 +57,15 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph,
|
|||||||
const IntersectionEdges &outgoing_edges,
|
const IntersectionEdges &outgoing_edges,
|
||||||
const std::unordered_set<EdgeID> &merged_edges);
|
const std::unordered_set<EdgeID> &merged_edges);
|
||||||
|
|
||||||
bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph,
|
guidance::IntersectionView
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
|
||||||
const RestrictionMap &restriction_map,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::vector<util::Coordinate> &node_coordinates,
|
||||||
const IntersectionEdgeGeometries &geometries,
|
const extractor::CompressedEdgeContainer &compressed_geometries,
|
||||||
const guidance::TurnLanesIndexedArray &turn_lanes_data,
|
const RestrictionMap &node_restriction_map,
|
||||||
const IntersectionEdge &from,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const IntersectionEdge &to);
|
const guidance::TurnLanesIndexedArray &turn_lanes_data,
|
||||||
|
const IntersectionEdge &incoming_edge);
|
||||||
double findEdgeBearing(const IntersectionEdgeGeometries &geometries, const EdgeID &edge);
|
|
||||||
|
|
||||||
double findEdgeLength(const IntersectionEdgeGeometries &geometries, const EdgeID &edge);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,42 +423,57 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
|
|
||||||
TurnDataExternalContainer turn_data_container;
|
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.
|
// Loop over all turns and generate new set of edges.
|
||||||
// Three nested loop look super-linear, but we are dealing with a (kind of)
|
// Three nested loop look super-linear, but we are dealing with a (kind of)
|
||||||
// linear number of turns only.
|
// linear number of turns only.
|
||||||
SuffixTable street_name_suffix_table(scripting_environment);
|
|
||||||
guidance::TurnAnalysis turn_analysis(m_node_based_graph,
|
guidance::TurnAnalysis turn_analysis(m_node_based_graph,
|
||||||
m_edge_based_node_container,
|
m_edge_based_node_container,
|
||||||
m_coordinates,
|
m_coordinates,
|
||||||
|
m_compressed_edge_container,
|
||||||
node_restriction_map,
|
node_restriction_map,
|
||||||
m_barrier_nodes,
|
m_barrier_nodes,
|
||||||
m_compressed_edge_container,
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table);
|
street_name_suffix_table);
|
||||||
|
|
||||||
util::guidance::LaneDataIdMap lane_data_map;
|
util::guidance::LaneDataIdMap lane_data_map;
|
||||||
guidance::lanes::TurnLaneHandler turn_lane_handler(m_node_based_graph,
|
guidance::lanes::TurnLaneHandler turn_lane_handler(m_node_based_graph,
|
||||||
m_edge_based_node_container,
|
m_edge_based_node_container,
|
||||||
|
m_coordinates,
|
||||||
|
m_compressed_edge_container,
|
||||||
|
node_restriction_map,
|
||||||
|
m_barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
lane_description_map,
|
lane_description_map,
|
||||||
turn_analysis,
|
turn_analysis,
|
||||||
lane_data_map);
|
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(),
|
bearing_class_by_node_based_node.resize(m_node_based_graph.GetNumberOfNodes(),
|
||||||
std::numeric_limits<std::uint32_t>::max());
|
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
|
// FIXME these need to be tuned in pre-allocated size
|
||||||
std::vector<TurnPenalty> turn_weight_penalties;
|
std::vector<TurnPenalty> turn_weight_penalties;
|
||||||
std::vector<TurnPenalty> turn_duration_penalties;
|
std::vector<TurnPenalty> turn_duration_penalties;
|
||||||
|
@ -15,12 +15,20 @@ namespace guidance
|
|||||||
DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_generator,
|
DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_generator,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table)
|
const SuffixTable &street_name_suffix_table)
|
||||||
: IntersectionHandler(node_based_graph,
|
: IntersectionHandler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
|
compressed_geometries,
|
||||||
|
node_restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator)
|
intersection_generator)
|
||||||
@ -64,12 +72,12 @@ operator()(const NodeID nid, const EdgeID source_edge_id, Intersection intersect
|
|||||||
});
|
});
|
||||||
|
|
||||||
(void)nid;
|
(void)nid;
|
||||||
OSRM_ASSERT(road != intersection.end(), coordinates[nid]);
|
OSRM_ASSERT(road != intersection.end(), node_coordinates[nid]);
|
||||||
|
|
||||||
if (road->instruction == TurnInstruction::INVALID())
|
if (road->instruction == TurnInstruction::INVALID())
|
||||||
return intersection;
|
return intersection;
|
||||||
|
|
||||||
OSRM_ASSERT(road->instruction.type == TurnType::Turn, coordinates[nid]);
|
OSRM_ASSERT(road->instruction.type == TurnType::Turn, node_coordinates[nid]);
|
||||||
|
|
||||||
road->instruction.type =
|
road->instruction.type =
|
||||||
isSameName(source_edge_id, road->eid) ? TurnType::NoTurn : TurnType::NewName;
|
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;
|
const constexpr bool USE_HIGH_PRECISION_MODE = !USE_LOW_PRECISION_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntersectionGenerator::IntersectionGenerator(
|
IntersectionGenerator::IntersectionGenerator(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const RestrictionMap &restriction_map,
|
||||||
const RestrictionMap &restriction_map,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::vector<util::Coordinate> &coordinates,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
const CompressedEdgeContainer &)
|
||||||
const CompressedEdgeContainer &compressed_edge_container)
|
|
||||||
: node_based_graph(node_based_graph), node_data_container(node_data_container),
|
: node_based_graph(node_based_graph), node_data_container(node_data_container),
|
||||||
restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates),
|
restriction_map(restriction_map), barrier_nodes(barrier_nodes), coordinates(coordinates)
|
||||||
coordinate_extractor(node_based_graph, compressed_edge_container, 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
|
IntersectionGenerationParameters
|
||||||
IntersectionGenerator::SkipDegreeTwoNodes(const NodeID starting_node, const EdgeID via_edge) const
|
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};
|
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 guidance
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "extractor/guidance/intersection_handler.hpp"
|
#include "extractor/guidance/intersection_handler.hpp"
|
||||||
#include "extractor/guidance/constants.hpp"
|
#include "extractor/guidance/constants.hpp"
|
||||||
|
#include "extractor/intersection/intersection_analysis.hpp"
|
||||||
|
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
#include "util/guidance/name_announcements.hpp"
|
#include "util/guidance/name_announcements.hpp"
|
||||||
@ -45,17 +46,29 @@ inline bool requiresAnnouncement(const util::NodeBasedDynamicGraph &node_based_g
|
|||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
IntersectionHandler::IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
IntersectionHandler::IntersectionHandler(
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const util::NameTable &name_table,
|
const std::vector<util::Coordinate> &node_coordinates,
|
||||||
const SuffixTable &street_name_suffix_table,
|
const extractor::CompressedEdgeContainer &compressed_geometries,
|
||||||
const IntersectionGenerator &intersection_generator)
|
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),
|
: 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),
|
street_name_suffix_table(street_name_suffix_table),
|
||||||
intersection_generator(intersection_generator),
|
intersection_generator(intersection_generator), graph_walker(node_based_graph,
|
||||||
graph_walker(node_based_graph, node_data_container, intersection_generator)
|
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
|
// or actually follow the full road. When 2399 lands, we can exchange here for a
|
||||||
// precalculated distance value.
|
// precalculated distance value.
|
||||||
const auto distance = util::coordinate_calculation::haversineDistance(
|
const auto distance = util::coordinate_calculation::haversineDistance(
|
||||||
coordinates[node_based_graph.GetTarget(via_edge)],
|
node_coordinates[node_based_graph.GetTarget(via_edge)],
|
||||||
coordinates[node_based_graph.GetTarget(road.eid)]);
|
node_coordinates[node_based_graph.GetTarget(road.eid)]);
|
||||||
|
|
||||||
return {TurnType::Turn,
|
return {TurnType::Turn,
|
||||||
(angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
|
(angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
|
||||||
@ -470,8 +483,15 @@ IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) cons
|
|||||||
return boost::none;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto intersection =
|
auto intersection = intersection::getConnectedRoads(
|
||||||
intersection_generator(intersection_parameters.nid, intersection_parameters.via_eid);
|
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);
|
auto intersection_node = node_based_graph.GetTarget(intersection_parameters.via_eid);
|
||||||
|
|
||||||
if (intersection.size() <= 2 || intersection.isTrafficSignalOrBarrier())
|
if (intersection.size() <= 2 || intersection.isTrafficSignalOrBarrier())
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "extractor/guidance/coordinate_extractor.hpp"
|
#include "extractor/guidance/coordinate_extractor.hpp"
|
||||||
#include "extractor/guidance/intersection_generator.hpp"
|
#include "extractor/guidance/intersection_generator.hpp"
|
||||||
#include "extractor/guidance/node_based_graph_walker.hpp"
|
#include "extractor/guidance/node_based_graph_walker.hpp"
|
||||||
|
#include "extractor/intersection/intersection_analysis.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
#include "extractor/suffix_table.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,
|
MergableRoadDetector::MergableRoadDetector(
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const std::vector<util::Coordinate> &node_coordinates,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const IntersectionGenerator &intersection_generator,
|
const std::vector<util::Coordinate> &node_coordinates,
|
||||||
const CoordinateExtractor &coordinate_extractor,
|
const extractor::CompressedEdgeContainer &compressed_geometries,
|
||||||
const util::NameTable &name_table,
|
const RestrictionMap &node_restriction_map,
|
||||||
const SuffixTable &street_name_suffix_table)
|
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_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),
|
coordinate_extractor(coordinate_extractor), name_table(name_table),
|
||||||
street_name_suffix_table(street_name_suffix_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
|
// selection data to the right and left
|
||||||
const auto constexpr SMALL_RANDOM_HOPLIMIT = 5;
|
const auto constexpr SMALL_RANDOM_HOPLIMIT = 5;
|
||||||
IntersectionFinderAccumulator left_accumulator(SMALL_RANDOM_HOPLIMIT, intersection_generator),
|
IntersectionFinderAccumulator left_accumulator(SMALL_RANDOM_HOPLIMIT,
|
||||||
right_accumulator(SMALL_RANDOM_HOPLIMIT, intersection_generator);
|
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
|
/* Standard following the straightmost road
|
||||||
* Since both items have the same id, we can `select` based on any setup
|
* 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,
|
/*requires entry=*/false,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
NodeBasedGraphWalker graph_walker(
|
NodeBasedGraphWalker graph_walker(node_based_graph,
|
||||||
node_based_graph, node_data_container, intersection_generator);
|
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);
|
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
|
/* if the intersection does not have a right turn, we continue onto the next one once
|
||||||
* (skipping over a single small side street)
|
* (skipping over a single small side street)
|
||||||
@ -266,7 +293,13 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
|
|||||||
|
|
||||||
// check if both intersections are connected
|
// check if both intersections are connected
|
||||||
IntersectionFinderAccumulator connect_accumulator(SMALL_RANDOM_HOPLIMIT,
|
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),
|
graph_walker.TraverseRoad(node_based_graph.GetTarget(left_accumulator.via_edge_id),
|
||||||
connector_turn->eid,
|
connector_turn->eid,
|
||||||
connect_accumulator,
|
connect_accumulator,
|
||||||
@ -281,8 +314,13 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node,
|
|||||||
const MergableRoadData &lhs,
|
const MergableRoadData &lhs,
|
||||||
const MergableRoadData &rhs) const
|
const MergableRoadData &rhs) const
|
||||||
{
|
{
|
||||||
NodeBasedGraphWalker graph_walker(
|
NodeBasedGraphWalker graph_walker(node_based_graph,
|
||||||
node_based_graph, node_data_container, intersection_generator);
|
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) {
|
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) {
|
||||||
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
|
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
|
||||||
SelectStraightmostRoadByNameAndOnlyChoice selector(
|
SelectStraightmostRoadByNameAndOnlyChoice selector(
|
||||||
@ -348,8 +386,13 @@ bool MergableRoadDetector::HaveSameDirection(const NodeID intersection_node,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Find a coordinate following a road that is far away
|
// Find a coordinate following a road that is far away
|
||||||
NodeBasedGraphWalker graph_walker(
|
NodeBasedGraphWalker graph_walker(node_based_graph,
|
||||||
node_based_graph, node_data_container, intersection_generator);
|
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) {
|
const auto getCoordinatesAlongWay = [&](const EdgeID edge_id, const double max_length) {
|
||||||
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
|
LengthLimitedCoordinateAccumulator accumulator(coordinate_extractor, max_length);
|
||||||
SelectStraightmostRoadByNameAndOnlyChoice selector(
|
SelectStraightmostRoadByNameAndOnlyChoice selector(
|
||||||
@ -517,8 +560,15 @@ bool MergableRoadDetector::IsLinkRoad(const NodeID intersection_node,
|
|||||||
{
|
{
|
||||||
const auto next_intersection_parameters =
|
const auto next_intersection_parameters =
|
||||||
intersection_generator.SkipDegreeTwoNodes(intersection_node, road.eid);
|
intersection_generator.SkipDegreeTwoNodes(intersection_node, road.eid);
|
||||||
const auto next_intersection_along_road = intersection_generator.GetConnectedRoads(
|
const auto next_intersection_along_road = intersection::getConnectedRoads(
|
||||||
next_intersection_parameters.nid, next_intersection_parameters.via_eid);
|
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) {
|
const auto extract_name_id = [this](const MergableRoadData &road) {
|
||||||
return node_data_container
|
return node_data_container
|
||||||
.GetAnnotation(node_based_graph.GetEdgeData(road.eid).annotation_data)
|
.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,
|
MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table,
|
const SuffixTable &street_name_suffix_table,
|
||||||
const IntersectionGenerator &intersection_generator)
|
const IntersectionGenerator &intersection_generator)
|
||||||
: IntersectionHandler(node_based_graph,
|
: IntersectionHandler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
coordinates,
|
||||||
|
compressed_geometries,
|
||||||
|
node_restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator)
|
intersection_generator)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "extractor/guidance/node_based_graph_walker.hpp"
|
#include "extractor/guidance/node_based_graph_walker.hpp"
|
||||||
|
#include "extractor/intersection/intersection_analysis.hpp"
|
||||||
#include "util/bearing.hpp"
|
#include "util/bearing.hpp"
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
|
|
||||||
@ -14,11 +15,18 @@ namespace guidance
|
|||||||
{
|
{
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
NodeBasedGraphWalker::NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph,
|
NodeBasedGraphWalker::NodeBasedGraphWalker(
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const IntersectionGenerator &intersection_generator)
|
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),
|
: 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(
|
IntersectionFinderAccumulator::IntersectionFinderAccumulator(
|
||||||
const std::uint8_t hop_limit, const IntersectionGenerator &intersection_generator)
|
const std::uint8_t hop_limit,
|
||||||
: hops(0), hop_limit(hop_limit), intersection_generator(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)
|
||||||
|
: 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;
|
nid = from_node;
|
||||||
via_edge_id = via_edge;
|
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
|
} // namespace guidance
|
||||||
|
@ -23,21 +23,28 @@ namespace extractor
|
|||||||
namespace guidance
|
namespace guidance
|
||||||
{
|
{
|
||||||
|
|
||||||
RoundaboutHandler::RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
RoundaboutHandler::RoundaboutHandler(
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
const std::vector<util::Coordinate> &coordinates,
|
||||||
const util::NameTable &name_table,
|
const extractor::CompressedEdgeContainer &compressed_geometries,
|
||||||
const SuffixTable &street_name_suffix_table,
|
const RestrictionMap &node_restriction_map,
|
||||||
const IntersectionGenerator &intersection_generator)
|
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,
|
: IntersectionHandler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
coordinates,
|
||||||
|
compressed_geometries,
|
||||||
|
node_restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator),
|
intersection_generator),
|
||||||
compressed_edge_container(compressed_edge_container),
|
coordinate_extractor(node_based_graph, compressed_geometries, coordinates)
|
||||||
coordinate_extractor(node_based_graph, compressed_edge_container, coordinates)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +150,7 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// there is a single non-roundabout edge
|
// 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 edge_range = node_based_graph.GetAdjacentEdgeRange(node);
|
||||||
const auto number_of_lanes_at_intersection = std::accumulate(
|
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) {
|
const auto getEdgeLength = [&](const NodeID source_node, EdgeID eid) {
|
||||||
double length = 0.;
|
double length = 0.;
|
||||||
auto last_coord = coordinates[source_node];
|
auto last_coord = node_coordinates[source_node];
|
||||||
const auto &edge_bucket = compressed_edge_container.GetBucketReference(eid);
|
const auto &edge_bucket = compressed_geometries.GetBucketReference(eid);
|
||||||
for (const auto &compressed_edge : edge_bucket)
|
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);
|
length += util::coordinate_calculation::haversineDistance(last_coord, next_coord);
|
||||||
last_coord = next_coord;
|
last_coord = next_coord;
|
||||||
}
|
}
|
||||||
|
@ -25,15 +25,24 @@ namespace guidance
|
|||||||
SliproadHandler::SliproadHandler(const IntersectionGenerator &intersection_generator,
|
SliproadHandler::SliproadHandler(const IntersectionGenerator &intersection_generator,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table)
|
const SuffixTable &street_name_suffix_table)
|
||||||
: IntersectionHandler(node_based_graph,
|
: IntersectionHandler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
|
compressed_geometries,
|
||||||
|
node_restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_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
|
// 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.
|
// 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{};
|
const SkipTrafficSignalBarrierRoadSelector road_selector{};
|
||||||
(void)graph_walker.TraverseRoad(intersection_node_id, // start node
|
(void)graph_walker.TraverseRoad(intersection_node_id, // start node
|
||||||
sliproad_edge, // onto edge
|
sliproad_edge, // onto edge
|
||||||
@ -372,8 +388,6 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
|
|||||||
//
|
//
|
||||||
// Sliproad Not a Sliproad
|
// Sliproad Not a Sliproad
|
||||||
{
|
{
|
||||||
const auto &coordinate_extractor = intersection_generator.GetCoordinateExtractor();
|
|
||||||
|
|
||||||
const NodeID start = intersection_node_id; // b
|
const NodeID start = intersection_node_id; // b
|
||||||
const EdgeID edge = sliproad_edge; // bd
|
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.
|
// Only check for curvature and ~90 degree when it makes sense to do so.
|
||||||
const constexpr auto MIN_LENGTH = 3.;
|
const constexpr auto MIN_LENGTH = 3.;
|
||||||
|
|
||||||
const auto length = haversineDistance(coordinates[intersection_node_id],
|
const auto length = haversineDistance(node_coordinates[intersection_node_id],
|
||||||
coordinates[main_road_intersection->node]);
|
node_coordinates[main_road_intersection->node]);
|
||||||
|
|
||||||
const double minimal_crossroad_angle_of_intersection = 40.;
|
const double minimal_crossroad_angle_of_intersection = 40.;
|
||||||
|
|
||||||
@ -546,8 +560,15 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto skip_traffic_light_intersection = intersection_generator(
|
const auto skip_traffic_light_intersection = intersection::getConnectedRoads(
|
||||||
node_based_graph.GetTarget(sliproad_edge), candidate_road.eid);
|
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() &&
|
if (skip_traffic_light_intersection.isTrafficSignalOrBarrier() &&
|
||||||
node_based_graph.GetTarget(skip_traffic_light_intersection[1].eid) ==
|
node_based_graph.GetTarget(skip_traffic_light_intersection[1].eid) ==
|
||||||
main_road_intersection->node)
|
main_road_intersection->node)
|
||||||
@ -656,8 +677,6 @@ bool SliproadHandler::nextIntersectionIsTooFarAway(const NodeID start, const Edg
|
|||||||
BOOST_ASSERT(start != SPECIAL_NODEID);
|
BOOST_ASSERT(start != SPECIAL_NODEID);
|
||||||
BOOST_ASSERT(onto != SPECIAL_EDGEID);
|
BOOST_ASSERT(onto != SPECIAL_EDGEID);
|
||||||
|
|
||||||
const auto &coordinate_extractor = intersection_generator.GetCoordinateExtractor();
|
|
||||||
|
|
||||||
// Base max distance threshold on the current road class we're on
|
// Base max distance threshold on the current road class we're on
|
||||||
const auto &data = node_based_graph.GetEdgeData(onto).flags;
|
const auto &data = node_based_graph.GetEdgeData(onto).flags;
|
||||||
const auto threshold = scaledThresholdByRoadClass(MAX_SLIPROAD_THRESHOLD, // <- scales down
|
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;
|
using namespace util::coordinate_calculation;
|
||||||
|
|
||||||
const auto first = coordinates[a];
|
const auto first = node_coordinates[a];
|
||||||
const auto second = coordinates[b];
|
const auto second = node_coordinates[b];
|
||||||
const auto third = coordinates[c];
|
const auto third = node_coordinates[c];
|
||||||
|
|
||||||
const auto length = haversineDistance(first, second);
|
const auto length = haversineDistance(first, second);
|
||||||
const auto heigth = haversineDistance(second, third);
|
const auto heigth = haversineDistance(second, third);
|
||||||
|
@ -11,15 +11,24 @@ namespace extractor
|
|||||||
namespace guidance
|
namespace guidance
|
||||||
{
|
{
|
||||||
|
|
||||||
SuppressModeHandler::SuppressModeHandler(const IntersectionGenerator &intersection_generator,
|
SuppressModeHandler::SuppressModeHandler(
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const IntersectionGenerator &intersection_generator,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const util::NameTable &name_table,
|
const std::vector<util::Coordinate> &coordinates,
|
||||||
const SuffixTable &street_name_suffix_table)
|
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,
|
: IntersectionHandler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
coordinates,
|
||||||
|
compressed_geometries,
|
||||||
|
node_restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator)
|
intersection_generator)
|
||||||
|
@ -23,60 +23,87 @@ using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
|
|||||||
|
|
||||||
TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
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 RestrictionMap &restriction_map,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
const guidance::TurnLanesIndexedArray &turn_lanes_data,
|
||||||
const util::NameTable &name_table,
|
const util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table)
|
const SuffixTable &street_name_suffix_table)
|
||||||
: node_based_graph(node_based_graph), intersection_generator(node_based_graph,
|
: node_based_graph(node_based_graph), intersection_generator(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
restriction_map,
|
restriction_map,
|
||||||
barrier_nodes,
|
barrier_nodes,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
compressed_edge_container),
|
compressed_edge_container),
|
||||||
roundabout_handler(node_based_graph,
|
roundabout_handler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
compressed_edge_container,
|
compressed_edge_container,
|
||||||
|
restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator),
|
intersection_generator),
|
||||||
motorway_handler(node_based_graph,
|
motorway_handler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
|
node_coordinates,
|
||||||
coordinates,
|
compressed_edge_container,
|
||||||
|
restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator),
|
intersection_generator),
|
||||||
turn_handler(node_based_graph,
|
turn_handler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
|
compressed_edge_container,
|
||||||
|
restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator),
|
intersection_generator),
|
||||||
sliproad_handler(intersection_generator,
|
sliproad_handler(intersection_generator,
|
||||||
node_based_graph,
|
node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
|
compressed_edge_container,
|
||||||
|
restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table),
|
street_name_suffix_table),
|
||||||
suppress_mode_handler(intersection_generator,
|
suppress_mode_handler(intersection_generator,
|
||||||
node_based_graph,
|
node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
|
compressed_edge_container,
|
||||||
|
restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table),
|
street_name_suffix_table),
|
||||||
driveway_handler(intersection_generator,
|
driveway_handler(intersection_generator,
|
||||||
node_based_graph,
|
node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
|
compressed_edge_container,
|
||||||
|
restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table),
|
street_name_suffix_table),
|
||||||
statistics_handler(intersection_generator,
|
statistics_handler(intersection_generator,
|
||||||
node_based_graph,
|
node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
node_coordinates,
|
||||||
|
compressed_edge_container,
|
||||||
|
restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table)
|
street_name_suffix_table)
|
||||||
{
|
{
|
||||||
@ -188,11 +215,6 @@ Intersection TurnAnalysis::setTurnTypes(const NodeID node_prior_to_intersection,
|
|||||||
return intersection;
|
return intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IntersectionGenerator &TurnAnalysis::GetIntersectionGenerator() const
|
|
||||||
{
|
|
||||||
return intersection_generator;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "extractor/guidance/turn_discovery.hpp"
|
#include "extractor/guidance/turn_discovery.hpp"
|
||||||
#include "extractor/guidance/constants.hpp"
|
#include "extractor/guidance/constants.hpp"
|
||||||
|
#include "extractor/intersection/intersection_analysis.hpp"
|
||||||
#include "util/bearing.hpp"
|
#include "util/bearing.hpp"
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
|
|
||||||
@ -14,16 +15,16 @@ namespace guidance
|
|||||||
namespace lanes
|
namespace lanes
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const constexpr bool USE_LOW_PRECISION_MODE = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool findPreviousIntersection(const NodeID node_v,
|
bool findPreviousIntersection(const NodeID node_v,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const Intersection &intersection,
|
const Intersection &intersection,
|
||||||
const IntersectionGenerator &intersection_generator,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
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
|
// output parameters
|
||||||
NodeID &result_node,
|
NodeID &result_node,
|
||||||
EdgeID &result_via_edge,
|
EdgeID &result_via_edge,
|
||||||
@ -43,7 +44,9 @@ bool findPreviousIntersection(const NodeID node_v,
|
|||||||
*/
|
*/
|
||||||
const constexpr double COMBINE_DISTANCE_CUTOFF = 30;
|
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 =
|
const auto coordinates_along_via_edge =
|
||||||
coordinate_extractor.GetForwardCoordinatesAlongRoad(node_v, via_edge);
|
coordinate_extractor.GetForwardCoordinatesAlongRoad(node_v, via_edge);
|
||||||
const auto via_edge_length =
|
const auto via_edge_length =
|
||||||
@ -71,7 +74,14 @@ bool findPreviousIntersection(const NodeID node_v,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto node_v_reverse_intersection =
|
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
|
// Continue along the straightmost turn. If there is no straight turn, we cannot find a valid
|
||||||
// previous intersection.
|
// previous intersection.
|
||||||
const auto straightmost_at_v_in_reverse =
|
const auto straightmost_at_v_in_reverse =
|
||||||
@ -83,8 +93,15 @@ bool findPreviousIntersection(const NodeID node_v,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid);
|
const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid);
|
||||||
const auto node_u_reverse_intersection = intersection_generator.GetConnectedRoads(
|
const auto node_u_reverse_intersection =
|
||||||
node_v, straightmost_at_v_in_reverse->eid, 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_v, straightmost_at_v_in_reverse->eid});
|
||||||
|
|
||||||
// now check that the u-turn at the given intersection connects to via-edge
|
// 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.
|
// 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;
|
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 =
|
const auto check_via_edge =
|
||||||
result_intersection.end() !=
|
result_intersection.end() !=
|
||||||
std::find_if(result_intersection.begin(),
|
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,
|
TurnHandler::TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
const std::vector<util::Coordinate> &coordinates,
|
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 util::NameTable &name_table,
|
||||||
const SuffixTable &street_name_suffix_table,
|
const SuffixTable &street_name_suffix_table,
|
||||||
const IntersectionGenerator &intersection_generator)
|
const IntersectionGenerator &intersection_generator)
|
||||||
: IntersectionHandler(node_based_graph,
|
: IntersectionHandler(node_based_graph,
|
||||||
node_data_container,
|
node_data_container,
|
||||||
coordinates,
|
coordinates,
|
||||||
|
compressed_geometries,
|
||||||
|
node_restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table,
|
street_name_suffix_table,
|
||||||
intersection_generator)
|
intersection_generator)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "extractor/guidance/turn_discovery.hpp"
|
#include "extractor/guidance/turn_discovery.hpp"
|
||||||
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
#include "extractor/guidance/turn_lane_augmentation.hpp"
|
||||||
#include "extractor/guidance/turn_lane_matcher.hpp"
|
#include "extractor/guidance/turn_lane_matcher.hpp"
|
||||||
|
#include "extractor/intersection/intersection_analysis.hpp"
|
||||||
#include "util/bearing.hpp"
|
#include "util/bearing.hpp"
|
||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
@ -35,14 +36,21 @@ std::size_t getNumberOfTurns(const Intersection &intersection)
|
|||||||
|
|
||||||
TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
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,
|
LaneDescriptionMap &lane_description_map,
|
||||||
const TurnAnalysis &turn_analysis,
|
const TurnAnalysis &turn_analysis,
|
||||||
util::guidance::LaneDataIdMap &id_map)
|
util::guidance::LaneDataIdMap &id_map)
|
||||||
: node_based_graph(node_based_graph), node_data_container(node_data_container),
|
: 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) =
|
std::tie(turn_lane_offsets, turn_lane_masks) = turn_lanes_data;
|
||||||
transformTurnLaneMapIntoArrays(lane_description_map);
|
|
||||||
count_handled = count_called = 0;
|
count_handled = count_called = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,8 +213,13 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at,
|
|||||||
if (findPreviousIntersection(at,
|
if (findPreviousIntersection(at,
|
||||||
via_edge,
|
via_edge,
|
||||||
intersection,
|
intersection,
|
||||||
turn_analysis.GetIntersectionGenerator(),
|
|
||||||
node_based_graph,
|
node_based_graph,
|
||||||
|
node_data_container,
|
||||||
|
node_coordinates,
|
||||||
|
compressed_geometries,
|
||||||
|
node_restriction_map,
|
||||||
|
barrier_nodes,
|
||||||
|
turn_lanes_data,
|
||||||
previous_node,
|
previous_node,
|
||||||
previous_via_edge,
|
previous_via_edge,
|
||||||
previous_intersection_view))
|
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
|
// find out about the next intersection. To check for valid matches, we also need the turn
|
||||||
// types. We can skip merging/angle adjustments, though
|
// types. We can skip merging/angle adjustments, though
|
||||||
const auto next_intersection = turn_analysis.AssignTurnTypes(
|
const auto next_intersection =
|
||||||
at, straightmost->eid, turn_analysis.GetIntersectionGenerator()(at, straightmost->eid));
|
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
|
// check where we can match turn lanes
|
||||||
std::size_t straightmost_tag_index = turn_lane_data.size();
|
std::size_t straightmost_tag_index = turn_lane_data.size();
|
||||||
|
@ -658,7 +658,7 @@ bool isTurnAllowed(const util::NodeBasedDynamicGraph &graph,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: the function adapts intersection geometry data to TurnAnalysis
|
// The function adapts intersection geometry data to TurnAnalysis
|
||||||
guidance::IntersectionView
|
guidance::IntersectionView
|
||||||
convertToIntersectionView(const util::NodeBasedDynamicGraph &graph,
|
convertToIntersectionView(const util::NodeBasedDynamicGraph &graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container,
|
const EdgeBasedNodeDataContainer &node_data_container,
|
||||||
@ -727,6 +727,62 @@ convertToIntersectionView(const util::NodeBasedDynamicGraph &graph,
|
|||||||
|
|
||||||
return intersection_view;
|
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