Abstracts away over differences in IntersectionView and Intersection.
Usage: struct MyIntersection : EnableIntersectionOps<MyIntersection> { }; Done. We require MyIntersection having at least the member attributes from IntersectionViewData but don't enforce a inheritance hierarchy.
This commit is contained in:
parent
928a6f0c7d
commit
9d8b92f418
@ -2,6 +2,7 @@
|
|||||||
#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_HPP_
|
#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_HPP_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "extractor/guidance/turn_instruction.hpp"
|
#include "extractor/guidance/turn_instruction.hpp"
|
||||||
@ -27,11 +28,19 @@ struct IntersectionShapeData
|
|||||||
|
|
||||||
inline auto makeCompareShapeDataByBearing(const double base_bearing)
|
inline auto makeCompareShapeDataByBearing(const double base_bearing)
|
||||||
{
|
{
|
||||||
return [base_bearing](const IntersectionShapeData &lhs, const IntersectionShapeData &rhs) {
|
return [base_bearing](const auto &lhs, const auto &rhs) {
|
||||||
return util::bearing::angleBetweenBearings(base_bearing, lhs.bearing) <
|
return util::bearing::angleBetweenBearings(base_bearing, lhs.bearing) <
|
||||||
util::bearing::angleBetweenBearings(base_bearing, rhs.bearing);
|
util::bearing::angleBetweenBearings(base_bearing, rhs.bearing);
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
inline auto makeCompareAngularDeviation(const double angle)
|
||||||
|
{
|
||||||
|
return [angle](const auto &lhs, const auto &rhs) {
|
||||||
|
return util::guidance::angularDeviation(lhs.angle, angle) <
|
||||||
|
util::guidance::angularDeviation(rhs.angle, angle);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// When viewing an intersection from an incoming edge, we can transform a shape into a view which
|
// When viewing an intersection from an incoming edge, we can transform a shape into a view which
|
||||||
// gives additional information on angles and whether a turn is allowed
|
// gives additional information on angles and whether a turn is allowed
|
||||||
@ -98,7 +107,25 @@ std::string toString(const ConnectedRoad &road);
|
|||||||
|
|
||||||
using IntersectionShape = std::vector<IntersectionShapeData>;
|
using IntersectionShape = std::vector<IntersectionShapeData>;
|
||||||
|
|
||||||
struct IntersectionView final : std::vector<IntersectionViewData>
|
// Common operations shared among IntersectionView and Intersections.
|
||||||
|
// Inherit to enable those operations on your compatible type. CRTP pattern.
|
||||||
|
template <typename Self> struct EnableIntersectionOps
|
||||||
|
{
|
||||||
|
// Find the turn whose angle offers the least angular deviation to the specified angle
|
||||||
|
// For turn angles [0, 90, 260] and a query of 180 we return the 260 degree turn.
|
||||||
|
auto findClosestTurn(double angle) const
|
||||||
|
{
|
||||||
|
auto comp = makeCompareAngularDeviation(angle);
|
||||||
|
return std::min_element(self()->begin(), self()->end(), comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto self() { return static_cast<Self *>(this); }
|
||||||
|
auto self() const { return static_cast<const Self *>(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IntersectionView final : std::vector<IntersectionViewData>, //
|
||||||
|
EnableIntersectionOps<IntersectionView> //
|
||||||
{
|
{
|
||||||
using Base = std::vector<IntersectionViewData>;
|
using Base = std::vector<IntersectionViewData>;
|
||||||
|
|
||||||
@ -106,21 +133,12 @@ struct IntersectionView final : std::vector<IntersectionViewData>
|
|||||||
{
|
{
|
||||||
return std::is_sorted(begin(), end(), std::mem_fn(&IntersectionViewData::CompareByAngle));
|
return std::is_sorted(begin(), end(), std::mem_fn(&IntersectionViewData::CompareByAngle));
|
||||||
};
|
};
|
||||||
|
|
||||||
Base::iterator findClosestTurn(double angle);
|
|
||||||
Base::const_iterator findClosestTurn(double angle) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Intersection final : std::vector<ConnectedRoad>
|
struct Intersection final : std::vector<ConnectedRoad>, //
|
||||||
|
EnableIntersectionOps<Intersection> //
|
||||||
{
|
{
|
||||||
using Base = std::vector<ConnectedRoad>;
|
using Base = std::vector<ConnectedRoad>;
|
||||||
/*
|
|
||||||
* find the turn whose angle offers the least angularDeviation to the specified angle
|
|
||||||
* E.g. for turn angles [0,90,260] and a query of 180 we return the 260 degree turn (difference
|
|
||||||
* 80 over the difference of 90 to the 90 degree turn)
|
|
||||||
*/
|
|
||||||
Base::iterator findClosestTurn(double angle);
|
|
||||||
Base::const_iterator findClosestTurn(double angle) const;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check validity of the intersection object. We assume a few basic properties every set of
|
* Check validity of the intersection object. We assume a few basic properties every set of
|
||||||
@ -134,9 +152,6 @@ struct Intersection final : std::vector<ConnectedRoad>
|
|||||||
std::uint8_t getHighestConnectedLaneCount(const util::NodeBasedDynamicGraph &) const;
|
std::uint8_t getHighestConnectedLaneCount(const util::NodeBasedDynamicGraph &) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
Intersection::const_iterator findClosestTurn(const Intersection &intersection, const double angle);
|
|
||||||
Intersection::iterator findClosestTurn(Intersection &intersection, const double angle);
|
|
||||||
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -57,16 +57,17 @@ class IntersectionNormalizer
|
|||||||
|
|
||||||
const IntersectionGenerator &intersection_generator;
|
const IntersectionGenerator &intersection_generator;
|
||||||
|
|
||||||
// check if two indices in an intersection can be seen as a single road in the perceived
|
/* check if two indices in an intersection can be seen as a single road in the perceived
|
||||||
// intersection representation. See below for an example. Utility function for
|
* intersection representation. See below for an example. Utility function for
|
||||||
// MergeSegregatedRoads. It also checks for neighboring merges.
|
* MergeSegregatedRoads. It also checks for neighboring merges.
|
||||||
// This is due possible segments where multiple roads could end up being merged into one.
|
* This is due possible segments where multiple roads could end up being merged into one.
|
||||||
// We only support merging two roads, not three or more, though.
|
* We only support merging two roads, not three or more, though.
|
||||||
// c c
|
* c c
|
||||||
// / /
|
* / /
|
||||||
// a - b -> a - b - (c,d) but not a - b d -> a,b,(cde)
|
* a - b -> a - b - (c,d) but not a - b d -> a,b,(cde)
|
||||||
// \ \
|
* \ \
|
||||||
// d e
|
* d e
|
||||||
|
*/
|
||||||
bool CanMerge(const NodeID intersection_node,
|
bool CanMerge(const NodeID intersection_node,
|
||||||
const IntersectionShape &intersection,
|
const IntersectionShape &intersection,
|
||||||
std::size_t first_index,
|
std::size_t first_index,
|
||||||
|
@ -14,7 +14,9 @@ IntersectionPrinter::IntersectionPrinter(
|
|||||||
const std::vector<extractor::QueryNode> &node_coordinates,
|
const std::vector<extractor::QueryNode> &node_coordinates,
|
||||||
const extractor::guidance::CoordinateExtractor &coordinate_extractor)
|
const extractor::guidance::CoordinateExtractor &coordinate_extractor)
|
||||||
: node_based_graph(node_based_graph), node_coordinates(node_coordinates),
|
: node_based_graph(node_based_graph), node_coordinates(node_coordinates),
|
||||||
coordinate_extractor(coordinate_extractor){};
|
coordinate_extractor(coordinate_extractor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
util::json::Array IntersectionPrinter::
|
util::json::Array IntersectionPrinter::
|
||||||
operator()(const NodeID intersection_node,
|
operator()(const NodeID intersection_node,
|
||||||
|
@ -55,7 +55,7 @@ double GetOffsetCorrectionFactor(const RoadClassification &road_classification)
|
|||||||
default:
|
default:
|
||||||
return 1.0;
|
return 1.0;
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CoordinateExtractor::CoordinateExtractor(
|
CoordinateExtractor::CoordinateExtractor(
|
||||||
|
@ -70,39 +70,6 @@ std::string toString(const ConnectedRoad &road)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntersectionView::Base::iterator IntersectionView::findClosestTurn(double angle)
|
|
||||||
{
|
|
||||||
// use the const operator to avoid code duplication
|
|
||||||
return begin() +
|
|
||||||
std::distance(cbegin(),
|
|
||||||
static_cast<const IntersectionView *>(this)->findClosestTurn(angle));
|
|
||||||
}
|
|
||||||
|
|
||||||
IntersectionView::Base::const_iterator IntersectionView::findClosestTurn(double angle) const
|
|
||||||
{
|
|
||||||
return std::min_element(
|
|
||||||
begin(), end(), [angle](const IntersectionViewData &lhs, const IntersectionViewData &rhs) {
|
|
||||||
return util::guidance::angularDeviation(lhs.angle, angle) <
|
|
||||||
util::guidance::angularDeviation(rhs.angle, angle);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Intersection::Base::iterator Intersection::findClosestTurn(double angle)
|
|
||||||
{
|
|
||||||
// use the const operator to avoid code duplication
|
|
||||||
return begin() +
|
|
||||||
std::distance(cbegin(), static_cast<const Intersection *>(this)->findClosestTurn(angle));
|
|
||||||
}
|
|
||||||
|
|
||||||
Intersection::Base::const_iterator Intersection::findClosestTurn(double angle) const
|
|
||||||
{
|
|
||||||
return std::min_element(
|
|
||||||
begin(), end(), [angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) {
|
|
||||||
return util::guidance::angularDeviation(lhs.angle, angle) <
|
|
||||||
util::guidance::angularDeviation(rhs.angle, angle);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Intersection::valid() const
|
bool Intersection::valid() const
|
||||||
{
|
{
|
||||||
return !empty() &&
|
return !empty() &&
|
||||||
|
Loading…
Reference in New Issue
Block a user