Propagating approach parameter to every phantom nodes search function.

Propagating approach parameter for plugins :
 - tabler
 - nearest
 - trip

Signed-off-by: FILLAU Jean-Maxime <jean-maxime.fillau@mapotempo.com>
This commit is contained in:
FILLAU Jean-Maxime 2017-05-23 12:23:22 +02:00 committed by Patrick Niklaus
parent 089c98a107
commit 82a149eb87
9 changed files with 201 additions and 121 deletions

View File

@ -651,54 +651,59 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance) const override final const float max_distance,
const engine::Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance); return m_geospatial_query->NearestPhantomNodesInRange(input_coordinate, max_distance, approach);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const engine::Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodesInRange( return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, bearing, bearing_range); input_coordinate, max_distance, bearing, bearing_range, approach);
}
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance) const override final const engine::Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance); return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, approach);
}
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance,
const engine::Approach approach) const override final
{
BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes(input_coordinate, max_results, max_distance, approach);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const engine::Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes( return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, bearing, bearing_range); input_coordinate, max_results, bearing, bearing_range, approach);
} }
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
@ -706,12 +711,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const engine::Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodes( return m_geospatial_query->NearestPhantomNodes(
input_coordinate, max_results, max_distance, bearing, bearing_range); input_coordinate, max_results, max_distance, bearing, bearing_range, approach);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
@ -725,35 +731,37 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
} }
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate, const double max_distance) const override final const util::Coordinate input_coordinate, const double max_distance, const engine::Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance); input_coordinate, max_distance, approach);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const engine::Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, max_distance, bearing, bearing_range); input_coordinate, max_distance, bearing, bearing_range, approach);
} }
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range) const override final const int bearing_range,
const engine::Approach approach) const override final
{ {
BOOST_ASSERT(m_geospatial_query.get()); BOOST_ASSERT(m_geospatial_query.get());
return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent( return m_geospatial_query->NearestPhantomNodeWithAlternativeFromBigComponent(
input_coordinate, bearing, bearing_range); input_coordinate, bearing, bearing_range, approach);
} }
unsigned GetCheckSum() const override final { return m_check_sum; } unsigned GetCheckSum() const override final { return m_check_sum; }

View File

@ -94,45 +94,54 @@ class BaseDataFacade
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance, const float max_distance,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
const engine::Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance) const = 0; const float max_distance,
const engine::Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
const engine::Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
virtual std::vector<PhantomNodeWithDistance> const engine::Approach approach) const = 0;
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results) const = 0;
virtual std::vector<PhantomNodeWithDistance> virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance) const = 0; const engine::Approach approach) const = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const double max_distance,
const engine::Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const engine::Approach approach) const = 0; const engine::Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const = 0; const double max_distance,
const engine::Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
const engine::Approach approach) const = 0;
virtual std::pair<PhantomNode, PhantomNode> virtual std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const int bearing, const int bearing,
const int bearing_range) const = 0; const int bearing_range,
const engine::Approach approach) const = 0;
virtual bool HasLaneData(const EdgeID id) const = 0; virtual bool HasLaneData(const EdgeID id) const = 0;
virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0; virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0;

View File

@ -53,11 +53,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Does not filter by small/big component! // Does not filter by small/big component!
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance) const const double max_distance,
const engine::Approach approach) const
{ {
auto results = auto results =
rtree.Nearest(input_coordinate, rtree.Nearest(input_coordinate,
[this](const CandidateSegment &segment) { return HasValidEdge(segment); }, [this, approach, &input_coordinate](const CandidateSegment &segment) {
return boolPairAnd(HasValidEdge(segment), approach_usage(input_coordinate, segment, approach));
},
[this, max_distance, input_coordinate](const std::size_t, [this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment) { const CandidateSegment &segment) {
return CheckSegmentDistance(input_coordinate, segment, max_distance); return CheckSegmentDistance(input_coordinate, segment, max_distance);
@ -72,13 +75,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodesInRange(const util::Coordinate input_coordinate, NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const const int bearing_range,
const engine::Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment) { [this, approach, &input_coordinate, bearing, bearing_range, max_distance](const CandidateSegment &segment) {
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), auto use_direction = boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
use_direction = boolPairAnd(use_direction,
approach_usage(input_coordinate, segment, approach));
return use_direction;
}, },
[this, max_distance, input_coordinate](const std::size_t, [this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment) { const CandidateSegment &segment) {
@ -94,13 +101,15 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const int bearing, const int bearing,
const int bearing_range) const const int bearing_range,
const engine::Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range](const CandidateSegment &segment) { [this, approach, &input_coordinate, bearing, bearing_range](const CandidateSegment &segment) {
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), auto use_direction = boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
return boolPairAnd(use_direction, approach_usage(input_coordinate, segment, approach));
}, },
[max_results](const std::size_t num_results, const CandidateSegment &) { [max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results; return num_results >= max_results;
@ -117,13 +126,15 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const unsigned max_results, const unsigned max_results,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const const int bearing_range,
const engine::Approach approach) const
{ {
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range](const CandidateSegment &segment) { [this, approach, &input_coordinate, bearing, bearing_range](const CandidateSegment &segment) {
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), auto use_direction = boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
return boolPairAnd(use_direction, approach_usage(input_coordinate, segment, approach));
}, },
[this, max_distance, max_results, input_coordinate](const std::size_t num_results, [this, max_distance, max_results, input_coordinate](const std::size_t num_results,
const CandidateSegment &segment) { const CandidateSegment &segment) {
@ -137,11 +148,15 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns max_results nearest PhantomNodes. // Returns max_results nearest PhantomNodes.
// Does not filter by small/big component! // Does not filter by small/big component!
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, const unsigned max_results) const NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results,
const engine::Approach approach) const
{ {
auto results = auto results =
rtree.Nearest(input_coordinate, rtree.Nearest(input_coordinate,
[this](const CandidateSegment &segment) { return HasValidEdge(segment); }, [this, approach, &input_coordinate](const CandidateSegment &segment) {
return boolPairAnd(HasValidEdge(segment), approach_usage(input_coordinate, segment, approach));
},
[max_results](const std::size_t num_results, const CandidateSegment &) { [max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results; return num_results >= max_results;
}); });
@ -154,11 +169,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::vector<PhantomNodeWithDistance> std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate, NearestPhantomNodes(const util::Coordinate input_coordinate,
const unsigned max_results, const unsigned max_results,
const double max_distance) const const double max_distance,
const engine::Approach approach) const
{ {
auto results = auto results =
rtree.Nearest(input_coordinate, rtree.Nearest(input_coordinate,
[this](const CandidateSegment &segment) { return HasValidEdge(segment); }, [this, approach, &input_coordinate](const CandidateSegment &segment) {
return boolPairAnd(HasValidEdge(segment), approach_usage(input_coordinate, segment, approach));
},
[this, max_distance, max_results, input_coordinate]( [this, max_distance, max_results, input_coordinate](
const std::size_t num_results, const CandidateSegment &segment) { const std::size_t num_results, const CandidateSegment &segment) {
return num_results >= max_results || return num_results >= max_results ||
@ -172,24 +190,27 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// a second phantom node is return that is the nearest coordinate in a big component. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance) const const double max_distance,
const engine::Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, &has_big_component, &has_small_component](const CandidateSegment &segment) { [this, approach, &input_coordinate, &has_big_component, &has_small_component](const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment);
use_directions = boolPairAnd(use_directions, valid_edges);
use_directions = boolPairAnd(use_directions, approach_usage(input_coordinate, segment, approach));
if (valid_edges.first || valid_edges.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment); has_big_component = has_big_component || !IsTinyComponent(segment);
has_small_component = has_small_component || IsTinyComponent(segment); has_small_component = has_small_component || IsTinyComponent(segment);
} }
use_directions = boolPairAnd(use_directions, valid_edges);
return use_directions; return use_directions;
}, },
[this, &has_big_component, max_distance, input_coordinate]( [this, &has_big_component, max_distance, input_coordinate](
@ -218,45 +239,23 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, &approach, &input_coordinate, &has_big_component, &has_small_component]( [this, approach, &input_coordinate, &has_big_component, &has_small_component](
const CandidateSegment &segment) { const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
auto use_directions = std::make_pair(use_segment, use_segment); auto use_directions = std::make_pair(use_segment, use_segment);
bool isOnewaySegment = !(segment.data.forward_segment_id.enabled &&
segment.data.reverse_segment_id.enabled);
if (!isOnewaySegment && approach != UNRESTRICTED)
{
// Check the counter clockwise
//
// input_coordinate
// |
// |
// segment.data.u ---------------- segment.data.v
bool input_coordinate_is_at_right = !util::coordinate_calculation::isCCW(
coordinates[segment.data.u], coordinates[segment.data.v], input_coordinate);
if(datafacade.IsLeftHandDriving())
input_coordinate_is_at_right = !input_coordinate_is_at_right;
// Apply the approach.
use_directions.first = use_directions.first && input_coordinate_is_at_right;
use_directions.second = use_directions.second && !input_coordinate_is_at_right;
}
if (!use_directions.first && !use_directions.second)
return use_directions;
const auto valid_edges = HasValidEdge(segment); const auto valid_edges = HasValidEdge(segment);
use_directions = boolPairAnd(use_directions, valid_edges);
use_directions = boolPairAnd(use_directions,
approach_usage(input_coordinate, segment, approach));
if (valid_edges.first || valid_edges.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment); has_big_component = has_big_component || !IsTinyComponent(segment);
has_small_component = has_small_component || IsTinyComponent(segment); has_small_component = has_small_component || IsTinyComponent(segment);
} }
use_directions = boolPairAnd(use_directions, valid_edges);
return use_directions; return use_directions;
}, },
[&has_big_component](const std::size_t num_results, const CandidateSegment &) { [&has_big_component](const std::size_t num_results, const CandidateSegment &) {
@ -276,13 +275,13 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
// Returns the nearest phantom node. If this phantom node is not from a big component // Returns the nearest phantom node. If this phantom node is not from a big component
// a second phantom node is return that is the nearest coordinate in a big component. // a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent( std::pair<PhantomNode, PhantomNode> NearestPhantomNodeWithAlternativeFromBigComponent(
const util::Coordinate input_coordinate, const int bearing, const int bearing_range) const const util::Coordinate input_coordinate, const int bearing, const int bearing_range, const engine::Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range, &has_big_component, &has_small_component]( [this, approach, &input_coordinate, bearing, bearing_range, &has_big_component, &has_small_component](
const CandidateSegment &segment) { const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
@ -294,6 +293,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
use_directions = use_directions =
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
use_directions = boolPairAnd(use_directions,
approach_usage(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment); has_big_component = has_big_component || !IsTinyComponent(segment);
@ -323,13 +325,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate input_coordinate,
const double max_distance, const double max_distance,
const int bearing, const int bearing,
const int bearing_range) const const int bearing_range,
const engine::Approach approach) const
{ {
bool has_small_component = false; bool has_small_component = false;
bool has_big_component = false; bool has_big_component = false;
auto results = rtree.Nearest( auto results = rtree.Nearest(
input_coordinate, input_coordinate,
[this, bearing, bearing_range, &has_big_component, &has_small_component]( [this, approach, &input_coordinate, bearing, bearing_range, &has_big_component, &has_small_component](
const CandidateSegment &segment) { const CandidateSegment &segment) {
auto use_segment = auto use_segment =
(!has_small_component || (!has_big_component && !IsTinyComponent(segment))); (!has_small_component || (!has_big_component && !IsTinyComponent(segment)));
@ -341,6 +344,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
use_directions = use_directions =
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
HasValidEdge(segment)); HasValidEdge(segment));
use_directions = boolPairAnd(use_directions,
approach_usage(input_coordinate, segment, approach));
if (use_directions.first || use_directions.second) if (use_directions.first || use_directions.second)
{ {
has_big_component = has_big_component || !IsTinyComponent(segment); has_big_component = has_big_component || !IsTinyComponent(segment);
@ -572,6 +578,32 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return datafacade.GetComponentID(data.forward_segment_id.id).is_tiny; return datafacade.GetComponentID(data.forward_segment_id.id).is_tiny;
} }
std::pair<bool, bool> approach_usage(const util::Coordinate &input_coordinate,
const CandidateSegment &segment,
const engine::Approach approach) const
{
bool isOnewaySegment = !(segment.data.forward_segment_id.enabled &&
segment.data.reverse_segment_id.enabled);
if (!isOnewaySegment && approach == CURB)
{
// Check the counter clockwise
//
// input_coordinate
// |
// |
// segment.data.u ---------------- segment.data.v
bool input_coordinate_is_at_right = !util::coordinate_calculation::isCCW(
coordinates[segment.data.u], coordinates[segment.data.v], input_coordinate);
if(datafacade.IsLeftHandDriving())
input_coordinate_is_at_right = !input_coordinate_is_at_right;
return std::make_pair(input_coordinate_is_at_right, (!input_coordinate_is_at_right));
}
return std::make_pair(true, true);
}
const RTreeT &rtree; const RTreeT &rtree;
const CoordinateList &coordinates; const CoordinateList &coordinates;
DataFacadeT &datafacade; DataFacadeT &datafacade;

View File

@ -120,9 +120,14 @@ class BasePlugin
const bool use_hints = !parameters.hints.empty(); const bool use_hints = !parameters.hints.empty();
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_approaches = !parameters.approaches.empty();
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
Approach approach = engine::Approach::UNRESTRICTED;
if (use_approaches && parameters.approaches[i])
approach = parameters.approaches[i].get();
if (use_hints && parameters.hints[i] && if (use_hints && parameters.hints[i] &&
parameters.hints[i]->IsValid(parameters.coordinates[i], facade)) parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
{ {
@ -139,12 +144,13 @@ class BasePlugin
facade.NearestPhantomNodesInRange(parameters.coordinates[i], facade.NearestPhantomNodesInRange(parameters.coordinates[i],
radiuses[i], radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
else else
{ {
phantom_nodes[i] = phantom_nodes[i] =
facade.NearestPhantomNodesInRange(parameters.coordinates[i], radiuses[i]); facade.NearestPhantomNodesInRange(parameters.coordinates[i], radiuses[i], approach);
} }
} }
@ -162,10 +168,15 @@ class BasePlugin
const bool use_hints = !parameters.hints.empty(); const bool use_hints = !parameters.hints.empty();
const bool use_bearings = !parameters.bearings.empty(); const bool use_bearings = !parameters.bearings.empty();
const bool use_radiuses = !parameters.radiuses.empty(); const bool use_radiuses = !parameters.radiuses.empty();
const bool use_approaches = !parameters.approaches.empty();
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size())) for (const auto i : util::irange<std::size_t>(0UL, parameters.coordinates.size()))
{ {
Approach approach = engine::Approach::UNRESTRICTED;
if (use_approaches && parameters.approaches[i])
approach = parameters.approaches[i].get();
if (use_hints && parameters.hints[i] && if (use_hints && parameters.hints[i] &&
parameters.hints[i]->IsValid(parameters.coordinates[i], facade)) parameters.hints[i]->IsValid(parameters.coordinates[i], facade))
{ {
@ -185,14 +196,16 @@ class BasePlugin
number_of_results, number_of_results,
*parameters.radiuses[i], *parameters.radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
else else
{ {
phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i], phantom_nodes[i] = facade.NearestPhantomNodes(parameters.coordinates[i],
number_of_results, number_of_results,
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
} }
else else
@ -200,12 +213,12 @@ class BasePlugin
if (use_radiuses && parameters.radiuses[i]) if (use_radiuses && parameters.radiuses[i])
{ {
phantom_nodes[i] = facade.NearestPhantomNodes( phantom_nodes[i] = facade.NearestPhantomNodes(
parameters.coordinates[i], number_of_results, *parameters.radiuses[i]); parameters.coordinates[i], number_of_results, *parameters.radiuses[i], approach);
} }
else else
{ {
phantom_nodes[i] = phantom_nodes[i] =
facade.NearestPhantomNodes(parameters.coordinates[i], number_of_results); facade.NearestPhantomNodes(parameters.coordinates[i], number_of_results, approach);
} }
} }
@ -252,7 +265,8 @@ class BasePlugin
parameters.coordinates[i], parameters.coordinates[i],
*parameters.radiuses[i], *parameters.radiuses[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach);
} }
else else
{ {
@ -260,7 +274,9 @@ class BasePlugin
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], parameters.coordinates[i],
parameters.bearings[i]->bearing, parameters.bearings[i]->bearing,
parameters.bearings[i]->range); parameters.bearings[i]->range,
approach
);
} }
} }
else else
@ -269,7 +285,7 @@ class BasePlugin
{ {
phantom_node_pairs[i] = phantom_node_pairs[i] =
facade.NearestPhantomNodeWithAlternativeFromBigComponent( facade.NearestPhantomNodeWithAlternativeFromBigComponent(
parameters.coordinates[i], *parameters.radiuses[i]); parameters.coordinates[i], *parameters.radiuses[i], approach);
} }
else else
{ {

View File

@ -28,6 +28,8 @@ std::string getWrongOptionHelp(const engine::api::NearestParameters &parameters)
PARAMETER_SIZE_MISMATCH_MSG, "bearings", parameters.bearings, coord_size, help); PARAMETER_SIZE_MISMATCH_MSG, "bearings", parameters.bearings, coord_size, help);
constrainParamSize( constrainParamSize(
PARAMETER_SIZE_MISMATCH_MSG, "radiuses", parameters.radiuses, coord_size, help); PARAMETER_SIZE_MISMATCH_MSG, "radiuses", parameters.radiuses, coord_size, help);
constrainParamSize(
PARAMETER_SIZE_MISMATCH_MSG, "approaches", parameters.approaches, coord_size, help);
return help; return help;
} }

View File

@ -47,7 +47,9 @@ std::string getWrongOptionHelp(const engine::api::TableParameters &parameters)
constrainParamSize( constrainParamSize(
PARAMETER_SIZE_MISMATCH_MSG, "bearings", parameters.bearings, coord_size, help) || PARAMETER_SIZE_MISMATCH_MSG, "bearings", parameters.bearings, coord_size, help) ||
constrainParamSize( constrainParamSize(
PARAMETER_SIZE_MISMATCH_MSG, "radiuses", parameters.radiuses, coord_size, help); PARAMETER_SIZE_MISMATCH_MSG, "radiuses", parameters.radiuses, coord_size, help) ||
constrainParamSize(
PARAMETER_SIZE_MISMATCH_MSG, "approaches", parameters.approaches, coord_size, help);
if (!param_size_mismatch && parameters.coordinates.size() < 2) if (!param_size_mismatch && parameters.coordinates.size() < 2)
{ {

View File

@ -28,7 +28,9 @@ std::string getWrongOptionHelp(const engine::api::TripParameters &parameters)
constrainParamSize( constrainParamSize(
PARAMETER_SIZE_MISMATCH_MSG, "bearings", parameters.bearings, coord_size, help) || PARAMETER_SIZE_MISMATCH_MSG, "bearings", parameters.bearings, coord_size, help) ||
constrainParamSize( constrainParamSize(
PARAMETER_SIZE_MISMATCH_MSG, "radiuses", parameters.radiuses, coord_size, help); PARAMETER_SIZE_MISMATCH_MSG, "radiuses", parameters.radiuses, coord_size, help) ||
constrainParamSize(
PARAMETER_SIZE_MISMATCH_MSG, "approaches", parameters.approaches, coord_size, help);
if (!param_size_mismatch && parameters.coordinates.size() < 2) if (!param_size_mismatch && parameters.coordinates.size() < 2)
{ {

View File

@ -99,14 +99,16 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/, NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/,
const float /*max_distance*/, const float /*max_distance*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/) const override const int /*bearing_range*/,
const engine::Approach /*approach*/) const override
{ {
return {}; return {};
} }
std::vector<engine::PhantomNodeWithDistance> std::vector<engine::PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/, NearestPhantomNodesInRange(const util::Coordinate /*input_coordinate*/,
const float /*max_distance*/) const override const float /*max_distance*/,
const engine::Approach /*approach*/) const override
{ {
return {}; return {};
} }
@ -116,7 +118,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
const unsigned /*max_results*/, const unsigned /*max_results*/,
const double /*max_distance*/, const double /*max_distance*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/) const override const int /*bearing_range*/,
const engine::Approach /*approach*/) const override
{ {
return {}; return {};
} }
@ -125,14 +128,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
NearestPhantomNodes(const util::Coordinate /*input_coordinate*/, NearestPhantomNodes(const util::Coordinate /*input_coordinate*/,
const unsigned /*max_results*/, const unsigned /*max_results*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/) const override const int /*bearing_range*/,
{ const engine::Approach /*approach*/) const override
return {};
}
std::vector<engine::PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate /*input_coordinate*/,
const unsigned /*max_results*/) const override
{ {
return {}; return {};
} }
@ -140,7 +137,16 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
std::vector<engine::PhantomNodeWithDistance> std::vector<engine::PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate /*input_coordinate*/, NearestPhantomNodes(const util::Coordinate /*input_coordinate*/,
const unsigned /*max_results*/, const unsigned /*max_results*/,
const double /*max_distance*/) const override const engine::Approach /*approach*/) const override
{
return {};
}
std::vector<engine::PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate /*input_coordinate*/,
const unsigned /*max_results*/,
const double /*max_distance*/,
const engine::Approach /*approach*/) const override
{ {
return {}; return {};
} }
@ -154,7 +160,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
std::pair<engine::PhantomNode, engine::PhantomNode> std::pair<engine::PhantomNode, engine::PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
const double /*max_distance*/) const override const double /*max_distance*/,
const engine::Approach /*approach*/) const override
{ {
return {}; return {};
} }
@ -163,7 +170,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
const double /*max_distance*/, const double /*max_distance*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/) const override const int /*bearing_range*/,
const engine::Approach /*approach*/) const override
{ {
return {}; return {};
} }
@ -171,7 +179,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
std::pair<engine::PhantomNode, engine::PhantomNode> std::pair<engine::PhantomNode, engine::PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/, NearestPhantomNodeWithAlternativeFromBigComponent(const util::Coordinate /*input_coordinate*/,
const int /*bearing*/, const int /*bearing*/,
const int /*bearing_range*/) const override const int /*bearing_range*/,
const engine::Approach /*approach*/) const override
{ {
return {}; return {};
} }

View File

@ -363,7 +363,7 @@ BOOST_AUTO_TEST_CASE(radius_regression_test)
Coordinate input(FloatLongitude{5.2}, FloatLatitude{5.0}); Coordinate input(FloatLongitude{5.2}, FloatLatitude{5.0});
{ {
auto results = query.NearestPhantomNodesInRange(input, 0.01); auto results = query.NearestPhantomNodesInRange(input, 0.01, osrm::engine::UNRESTRICTED);
BOOST_CHECK_EQUAL(results.size(), 0); BOOST_CHECK_EQUAL(results.size(), 0);
} }
} }
@ -390,19 +390,19 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
Coordinate input(FloatLongitude{5.1}, FloatLatitude{5.0}); Coordinate input(FloatLongitude{5.1}, FloatLatitude{5.0});
{ {
auto results = query.NearestPhantomNodes(input, 5); auto results = query.NearestPhantomNodes(input, 5, osrm::engine::UNRESTRICTED);
BOOST_CHECK_EQUAL(results.size(), 2); BOOST_CHECK_EQUAL(results.size(), 2);
BOOST_CHECK_EQUAL(results.back().phantom_node.forward_segment_id.id, 0); BOOST_CHECK_EQUAL(results.back().phantom_node.forward_segment_id.id, 0);
BOOST_CHECK_EQUAL(results.back().phantom_node.reverse_segment_id.id, 1); BOOST_CHECK_EQUAL(results.back().phantom_node.reverse_segment_id.id, 1);
} }
{ {
auto results = query.NearestPhantomNodes(input, 5, 270, 10); auto results = query.NearestPhantomNodes(input, 5, 270, 10, osrm::engine::UNRESTRICTED);
BOOST_CHECK_EQUAL(results.size(), 0); BOOST_CHECK_EQUAL(results.size(), 0);
} }
{ {
auto results = query.NearestPhantomNodes(input, 5, 45, 10); auto results = query.NearestPhantomNodes(input, 5, 45, 10, osrm::engine::UNRESTRICTED);
BOOST_CHECK_EQUAL(results.size(), 2); BOOST_CHECK_EQUAL(results.size(), 2);
BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled); BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled);
@ -415,17 +415,17 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
} }
{ {
auto results = query.NearestPhantomNodesInRange(input, 11000); auto results = query.NearestPhantomNodesInRange(input, 11000, osrm::engine::UNRESTRICTED);
BOOST_CHECK_EQUAL(results.size(), 2); BOOST_CHECK_EQUAL(results.size(), 2);
} }
{ {
auto results = query.NearestPhantomNodesInRange(input, 11000, 270, 10); auto results = query.NearestPhantomNodesInRange(input, 11000, 270, 10, osrm::engine::UNRESTRICTED);
BOOST_CHECK_EQUAL(results.size(), 0); BOOST_CHECK_EQUAL(results.size(), 0);
} }
{ {
auto results = query.NearestPhantomNodesInRange(input, 11000, 45, 10); auto results = query.NearestPhantomNodesInRange(input, 11000, 45, 10, osrm::engine::UNRESTRICTED);
BOOST_CHECK_EQUAL(results.size(), 2); BOOST_CHECK_EQUAL(results.size(), 2);
BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled); BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled);