Make adjustment of restricted maneuver weight conditional on query-time parameter.

This commit is contained in:
Daniel Patterson 2019-01-08 00:00:55 -08:00
parent da4f700f80
commit d068c7de59
No known key found for this signature in database
GPG Key ID: 19C12BE1725A028B
20 changed files with 185 additions and 57 deletions

View File

@ -305,3 +305,58 @@ Feature: Car - Restricted access
| primary | psv | | | primary | psv | |
| primary | no | | | primary | no | |
| primary | customers | x | | primary | customers | x |
# TODO: implement this for MLD
@ch
Scenario: Car - routing over private roads (default penalty)
Given the node map
"""
a f
| |
b---1---e
| |
c-------d
"""
And the ways
| nodes | access |
| ab | |
| bc | |
| cd | |
| de | |
| ef | |
| be | private |
When I route I should get
| from | to | route |
| a | f | ab,bc,cd,de,ef,ef |
| a | 1 | ab,be,be |
# TODO: implement this for MLD
@ch
Scenario: Car - routing over private roads (no penalty)
Given the node map
"""
a f
| |
b---1---e
| |
c-------d
"""
And the ways
| nodes | access |
| ab | |
| bc | |
| cd | |
| de | |
| ef | |
| be | private |
And the query options
| permit | private |
When I route I should get
| from | to | route |
| a | f | ab,be,ef,ef |
| a | 1 | ab,be,be |

View File

@ -69,6 +69,7 @@ struct BaseParameters
std::vector<boost::optional<Bearing>> bearings; std::vector<boost::optional<Bearing>> bearings;
std::vector<boost::optional<Approach>> approaches; std::vector<boost::optional<Approach>> approaches;
std::vector<std::string> exclude; std::vector<std::string> exclude;
std::vector<std::string> permit;
// Adds hints to response which can be included in subsequent requests, see `hints` above. // Adds hints to response which can be included in subsequent requests, see `hints` above.
bool generate_hints = true; bool generate_hints = true;
@ -79,9 +80,10 @@ struct BaseParameters
std::vector<boost::optional<Bearing>> bearings_ = {}, std::vector<boost::optional<Bearing>> bearings_ = {},
std::vector<boost::optional<Approach>> approaches_ = {}, std::vector<boost::optional<Approach>> approaches_ = {},
bool generate_hints_ = true, bool generate_hints_ = true,
std::vector<std::string> exclude = {}) std::vector<std::string> exclude = {},
std::vector<std::string> permit = {})
: coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_), : coordinates(coordinates_), hints(hints_), radiuses(radiuses_), bearings(bearings_),
approaches(approaches_), exclude(std::move(exclude)), generate_hints(generate_hints_) approaches(approaches_), exclude(std::move(exclude)), permit(std::move(permit)), generate_hints(generate_hints_)
{ {
} }
@ -91,6 +93,7 @@ struct BaseParameters
return (hints.empty() || hints.size() == coordinates.size()) && return (hints.empty() || hints.size() == coordinates.size()) &&
(bearings.empty() || bearings.size() == coordinates.size()) && (bearings.empty() || bearings.size() == coordinates.size()) &&
(radiuses.empty() || radiuses.size() == coordinates.size()) && (radiuses.empty() || radiuses.size() == coordinates.size()) &&
(permit.empty() || (permit.size() == 1 && permit.front() == "private")) &&
(approaches.empty() || approaches.size() == coordinates.size()) && (approaches.empty() || approaches.size() == coordinates.size()) &&
std::all_of(bearings.begin(), std::all_of(bearings.begin(),
bearings.end(), bearings.end(),

View File

@ -33,7 +33,8 @@ class TripPlugin final : public BasePlugin
InternalRouteResult ComputeRoute(const RoutingAlgorithmsInterface &algorithms, InternalRouteResult ComputeRoute(const RoutingAlgorithmsInterface &algorithms,
const std::vector<PhantomNode> &phantom_node_list, const std::vector<PhantomNode> &phantom_node_list,
const std::vector<NodeID> &trip, const std::vector<NodeID> &trip,
const bool roundtrip) const; const bool roundtrip,
const bool permit_private) const;
public: public:
explicit TripPlugin(const int max_locations_trip_) : max_locations_trip(max_locations_trip_) {} explicit TripPlugin(const int max_locations_trip_) : max_locations_trip(max_locations_trip_) {}

View File

@ -25,10 +25,11 @@ class RoutingAlgorithmsInterface
virtual InternalRouteResult virtual InternalRouteResult
ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair, ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair,
const boost::optional<bool> continue_straight_at_waypoint) const = 0; const boost::optional<bool> continue_straight_at_waypoint,
const bool permit_private) const = 0;
virtual InternalRouteResult virtual InternalRouteResult
DirectShortestPathSearch(const PhantomNodes &phantom_node_pair) const = 0; DirectShortestPathSearch(const PhantomNodes &phantom_node_pair, const bool permit_private) const = 0;
virtual std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> virtual std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>>
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes, ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
@ -78,10 +79,11 @@ template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgo
InternalRouteResult ShortestPathSearch( InternalRouteResult ShortestPathSearch(
const std::vector<PhantomNodes> &phantom_node_pair, const std::vector<PhantomNodes> &phantom_node_pair,
const boost::optional<bool> continue_straight_at_waypoint) const final override; const boost::optional<bool> continue_straight_at_waypoint,
const bool permit_private) const final override;
InternalRouteResult InternalRouteResult
DirectShortestPathSearch(const PhantomNodes &phantom_nodes) const final override; DirectShortestPathSearch(const PhantomNodes &phantom_nodes, const bool permit_private) const final override;
virtual std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>> virtual std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>>
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes, ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
@ -161,17 +163,18 @@ RoutingAlgorithms<Algorithm>::AlternativePathSearch(const PhantomNodes &phantom_
template <typename Algorithm> template <typename Algorithm>
InternalRouteResult RoutingAlgorithms<Algorithm>::ShortestPathSearch( InternalRouteResult RoutingAlgorithms<Algorithm>::ShortestPathSearch(
const std::vector<PhantomNodes> &phantom_node_pair, const std::vector<PhantomNodes> &phantom_node_pair,
const boost::optional<bool> continue_straight_at_waypoint) const const boost::optional<bool> continue_straight_at_waypoint,
const bool permit_private) const
{ {
return routing_algorithms::shortestPathSearch( return routing_algorithms::shortestPathSearch(
heaps, *facade, phantom_node_pair, continue_straight_at_waypoint); heaps, *facade, phantom_node_pair, continue_straight_at_waypoint, permit_private);
} }
template <typename Algorithm> template <typename Algorithm>
InternalRouteResult InternalRouteResult
RoutingAlgorithms<Algorithm>::DirectShortestPathSearch(const PhantomNodes &phantom_nodes) const RoutingAlgorithms<Algorithm>::DirectShortestPathSearch(const PhantomNodes &phantom_nodes, const bool permit_private) const
{ {
return routing_algorithms::directShortestPathSearch(heaps, *facade, phantom_nodes); return routing_algorithms::directShortestPathSearch(heaps, *facade, phantom_nodes, permit_private);
} }
template <typename Algorithm> template <typename Algorithm>

View File

@ -24,7 +24,8 @@ namespace routing_algorithms
template <typename Algorithm> template <typename Algorithm>
InternalRouteResult directShortestPathSearch(SearchEngineData<Algorithm> &engine_working_data, InternalRouteResult directShortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade, const DataFacade<Algorithm> &facade,
const PhantomNodes &phantom_nodes); const PhantomNodes &phantom_nodes,
const bool permit_private);
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine

View File

@ -37,6 +37,8 @@ namespace routing_algorithms
static constexpr bool FORWARD_DIRECTION = true; static constexpr bool FORWARD_DIRECTION = true;
static constexpr bool REVERSE_DIRECTION = false; static constexpr bool REVERSE_DIRECTION = false;
static constexpr bool DO_NOT_FORCE_LOOPS = false; static constexpr bool DO_NOT_FORCE_LOOPS = false;
static constexpr bool PERMIT_PRIVATE = true;
static constexpr bool AVOID_PRIVATE = false;
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom); bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom); bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom);

View File

@ -52,7 +52,8 @@ template <bool DIRECTION>
void relaxOutgoingEdges(const DataFacade<Algorithm> &facade, void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const NodeID node, const NodeID node,
const EdgeWeight weight, const EdgeWeight weight,
SearchEngineData<Algorithm>::QueryHeap &heap) SearchEngineData<Algorithm>::QueryHeap &heap,
const bool permit_private)
{ {
for (const auto edge : facade.GetAdjacentEdgeRange(node)) for (const auto edge : facade.GetAdjacentEdgeRange(node))
{ {
@ -63,7 +64,8 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const EdgeWeight edge_weight = data.weight; const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const EdgeWeight to_weight = weight + edge_weight; const EdgeWeight to_weight = weight + edge_weight + ((!permit_private && data.maneuver_restricted) ? std::numeric_limits<TurnPenalty>::max() : 0);
// const EdgeWeight to_weight = weight + edge_weight;
// New Node discovered -> Add to Heap + Node Info Storage // New Node discovered -> Add to Heap + Node Info Storage
if (!heap.WasInserted(to)) if (!heap.WasInserted(to))
@ -120,7 +122,8 @@ void routingStep(const DataFacade<Algorithm> &facade,
EdgeWeight &upper_bound, EdgeWeight &upper_bound,
EdgeWeight min_edge_offset, EdgeWeight min_edge_offset,
const bool force_loop_forward, const bool force_loop_forward,
const bool force_loop_reverse) const bool force_loop_reverse,
const bool permit_private)
{ {
const NodeID node = forward_heap.DeleteMin(); const NodeID node = forward_heap.DeleteMin();
const EdgeWeight weight = forward_heap.GetKey(node); const EdgeWeight weight = forward_heap.GetKey(node);
@ -182,7 +185,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
return; return;
} }
relaxOutgoingEdges<DIRECTION>(facade, node, weight, forward_heap); relaxOutgoingEdges<DIRECTION>(facade, node, weight, forward_heap, permit_private);
} }
template <bool UseDuration> template <bool UseDuration>
@ -471,7 +474,8 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
const bool force_loop_forward, const bool force_loop_forward,
const bool force_loop_reverse, const bool force_loop_reverse,
const PhantomNodes &phantom_nodes, const PhantomNodes &phantom_nodes,
const int duration_upper_bound = INVALID_EDGE_WEIGHT); const int duration_upper_bound,
const bool permit_private);
// Requires the heaps for be empty // Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function, // If heaps should be adjusted to be initialized outside of this function,
@ -482,7 +486,8 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap, SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom, const PhantomNode &source_phantom,
const PhantomNode &target_phantom, const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT); int duration_upper_bound,
const bool permit_private);
} // namespace ch } // namespace ch
} // namespace routing_algorithms } // namespace routing_algorithms

View File

@ -520,7 +520,8 @@ inline void search(SearchEngineData<Algorithm> &engine_working_data,
const bool force_loop_forward, const bool force_loop_forward,
const bool force_loop_reverse, const bool force_loop_reverse,
const PhantomNodes &phantom_nodes, const PhantomNodes &phantom_nodes,
const EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT) const EdgeWeight weight_upper_bound,
const bool /* permit_private */) // danpat TODO: implement this pls :-P
{ {
// TODO: change search calling interface to use unpacked_edges result // TODO: change search calling interface to use unpacked_edges result
std::tie(weight, unpacked_nodes, std::ignore) = search(engine_working_data, std::tie(weight, unpacked_nodes, std::ignore) = search(engine_working_data,
@ -571,7 +572,8 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap, typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom, const PhantomNode &source_phantom,
const PhantomNode &target_phantom, const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT) EdgeWeight weight_upper_bound,
const bool /* permit_private */) // danpat TODO: implement this
{ {
forward_heap.Clear(); forward_heap.Clear();
reverse_heap.Clear(); reverse_heap.Clear();

View File

@ -17,7 +17,8 @@ template <typename Algorithm>
InternalRouteResult shortestPathSearch(SearchEngineData<Algorithm> &engine_working_data, InternalRouteResult shortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade, const DataFacade<Algorithm> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector, const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint); const boost::optional<bool> continue_straight_at_waypoint,
const bool permit_private);
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine

View File

@ -34,7 +34,8 @@ void searchWithUTurn(SearchEngineData<Algorithm> &engine_working_data,
const int total_weight_to_forward, const int total_weight_to_forward,
const int total_weight_to_reverse, const int total_weight_to_reverse,
int &new_total_weight, int &new_total_weight,
std::vector<NodeID> &leg_packed_path) std::vector<NodeID> &leg_packed_path,
const bool permit_private)
{ {
forward_heap.Clear(); forward_heap.Clear();
reverse_heap.Clear(); reverse_heap.Clear();
@ -79,7 +80,9 @@ void searchWithUTurn(SearchEngineData<Algorithm> &engine_working_data,
leg_packed_path, leg_packed_path,
needs_loop_forwards, needs_loop_forwards,
needs_loop_backwards, needs_loop_backwards,
{source_phantom, target_phantom}); {source_phantom, target_phantom},
MAXIMAL_EDGE_WEIGHT,
permit_private);
// if no route is found between two parts of the via-route, the entire route becomes // if no route is found between two parts of the via-route, the entire route becomes
// invalid. Adding to invalid edge weight sadly doesn't return an invalid edge weight. Here // invalid. Adding to invalid edge weight sadly doesn't return an invalid edge weight. Here
@ -107,7 +110,8 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
int &new_total_weight_to_forward, int &new_total_weight_to_forward,
int &new_total_weight_to_reverse, int &new_total_weight_to_reverse,
std::vector<NodeID> &leg_packed_path_forward, std::vector<NodeID> &leg_packed_path_forward,
std::vector<NodeID> &leg_packed_path_reverse) std::vector<NodeID> &leg_packed_path_reverse,
const bool permit_private)
{ {
if (search_to_forward_node) if (search_to_forward_node)
{ {
@ -140,7 +144,9 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
leg_packed_path_forward, leg_packed_path_forward,
needsLoopForward(source_phantom, target_phantom), needsLoopForward(source_phantom, target_phantom),
routing_algorithms::DO_NOT_FORCE_LOOP, routing_algorithms::DO_NOT_FORCE_LOOP,
{source_phantom, target_phantom}); {source_phantom, target_phantom},
MAXIMAL_EDGE_WEIGHT,
permit_private);
} }
if (search_to_reverse_node) if (search_to_reverse_node)
@ -173,7 +179,9 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
leg_packed_path_reverse, leg_packed_path_reverse,
routing_algorithms::DO_NOT_FORCE_LOOP, routing_algorithms::DO_NOT_FORCE_LOOP,
needsLoopBackwards(source_phantom, target_phantom), needsLoopBackwards(source_phantom, target_phantom),
{source_phantom, target_phantom}); {source_phantom, target_phantom},
MAXIMAL_EDGE_WEIGHT,
permit_private);
} }
} }
@ -232,7 +240,8 @@ template <typename Algorithm>
InternalRouteResult shortestPathSearch(SearchEngineData<Algorithm> &engine_working_data, InternalRouteResult shortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade, const DataFacade<Algorithm> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector, const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint) const boost::optional<bool> continue_straight_at_waypoint,
const bool permit_private)
{ {
InternalRouteResult raw_route_data; InternalRouteResult raw_route_data;
raw_route_data.segment_end_coordinates = phantom_nodes_vector; raw_route_data.segment_end_coordinates = phantom_nodes_vector;
@ -297,7 +306,8 @@ InternalRouteResult shortestPathSearch(SearchEngineData<Algorithm> &engine_worki
total_weight_to_forward, total_weight_to_forward,
total_weight_to_reverse, total_weight_to_reverse,
new_total_weight_to_forward, new_total_weight_to_forward,
packed_leg_to_forward); packed_leg_to_forward,
permit_private);
// if only the reverse node is valid (e.g. when using the match plugin) we // if only the reverse node is valid (e.g. when using the match plugin) we
// actually need to move // actually need to move
if (!target_phantom.IsValidForwardTarget()) if (!target_phantom.IsValidForwardTarget())
@ -335,7 +345,8 @@ InternalRouteResult shortestPathSearch(SearchEngineData<Algorithm> &engine_worki
new_total_weight_to_forward, new_total_weight_to_forward,
new_total_weight_to_reverse, new_total_weight_to_reverse,
packed_leg_to_forward, packed_leg_to_forward,
packed_leg_to_reverse); packed_leg_to_reverse,
permit_private);
} }
} }

View File

@ -166,12 +166,17 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
(qi::as_string[+qi::char_("a-zA-Z0-9")] % (qi::as_string[+qi::char_("a-zA-Z0-9")] %
',')[ph::bind(&engine::api::BaseParameters::exclude, qi::_r1) = qi::_1]; ',')[ph::bind(&engine::api::BaseParameters::exclude, qi::_r1) = qi::_1];
permit_rule = qi::lit("permit=") >
(qi::as_string[+qi::char_("a-zA-Z0-9")] %
',')[ph::bind(&engine::api::BaseParameters::permit, qi::_r1) = qi::_1];
base_rule = radiuses_rule(qi::_r1) // base_rule = radiuses_rule(qi::_r1) //
| hints_rule(qi::_r1) // | hints_rule(qi::_r1) //
| bearings_rule(qi::_r1) // | bearings_rule(qi::_r1) //
| generate_hints_rule(qi::_r1) // | generate_hints_rule(qi::_r1) //
| approach_rule(qi::_r1) // | approach_rule(qi::_r1) //
| exclude_rule(qi::_r1); | exclude_rule(qi::_r1) //
| permit_rule(qi::_r1);
} }
protected: protected:
@ -188,6 +193,7 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
qi::rule<Iterator, Signature> generate_hints_rule; qi::rule<Iterator, Signature> generate_hints_rule;
qi::rule<Iterator, Signature> approach_rule; qi::rule<Iterator, Signature> approach_rule;
qi::rule<Iterator, Signature> exclude_rule; qi::rule<Iterator, Signature> exclude_rule;
qi::rule<Iterator, Signature> permit_rule;
qi::rule<Iterator, osrm::engine::Bearing()> bearing_rule; qi::rule<Iterator, osrm::engine::Bearing()> bearing_rule;
qi::rule<Iterator, osrm::util::Coordinate()> location_rule; qi::rule<Iterator, osrm::util::Coordinate()> location_rule;

View File

@ -112,6 +112,7 @@ static const SegmentDuration INVALID_SEGMENT_DURATION = (1u << SEGMENT_DURATION_
static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - 1; static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - 1;
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1; static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1;
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max(); static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
static const EdgeWeight MAXIMAL_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max(); static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max();
static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max(); static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max(); static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();

View File

@ -289,7 +289,7 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
// we split the phantom nodes anyway and only have bi-directional phantom nodes for // we split the phantom nodes anyway and only have bi-directional phantom nodes for
// possible uturns // possible uturns
sub_routes[index] = sub_routes[index] =
algorithms.ShortestPathSearch(sub_routes[index].segment_end_coordinates, {false}); algorithms.ShortestPathSearch(sub_routes[index].segment_end_coordinates, {false}, routing_algorithms::PERMIT_PRIVATE);
BOOST_ASSERT(sub_routes[index].shortest_path_weight != INVALID_EDGE_WEIGHT); BOOST_ASSERT(sub_routes[index].shortest_path_weight != INVALID_EDGE_WEIGHT);
if (collapse_legs) if (collapse_legs)
{ {

View File

@ -55,7 +55,8 @@ bool IsSupportedParameterCombination(const bool fixed_start,
InternalRouteResult TripPlugin::ComputeRoute(const RoutingAlgorithmsInterface &algorithms, InternalRouteResult TripPlugin::ComputeRoute(const RoutingAlgorithmsInterface &algorithms,
const std::vector<PhantomNode> &snapped_phantoms, const std::vector<PhantomNode> &snapped_phantoms,
const std::vector<NodeID> &trip, const std::vector<NodeID> &trip,
const bool roundtrip) const const bool roundtrip,
const bool permit_private = false) const
{ {
InternalRouteResult min_route; InternalRouteResult min_route;
// given the final trip, compute total duration and return the route and location permutation // given the final trip, compute total duration and return the route and location permutation
@ -85,7 +86,7 @@ InternalRouteResult TripPlugin::ComputeRoute(const RoutingAlgorithmsInterface &a
BOOST_ASSERT(min_route.segment_end_coordinates.size() == trip.size() - 1); BOOST_ASSERT(min_route.segment_end_coordinates.size() == trip.size() - 1);
} }
min_route = algorithms.ShortestPathSearch(min_route.segment_end_coordinates, {false}); min_route = algorithms.ShortestPathSearch(min_route.segment_end_coordinates, {false}, permit_private);
BOOST_ASSERT_MSG(min_route.shortest_path_weight < INVALID_EDGE_WEIGHT, "unroutable route"); BOOST_ASSERT_MSG(min_route.shortest_path_weight < INVALID_EDGE_WEIGHT, "unroutable route");
return min_route; return min_route;
} }
@ -267,9 +268,12 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
std::rotate(std::begin(duration_trip), desired_start_index, std::end(duration_trip)); std::rotate(std::begin(duration_trip), desired_start_index, std::end(duration_trip));
} }
// TODO validate:
const bool permit_private = parameters.permit.size() == 1 && parameters.permit.front() == "private";
// get the route when visiting all destinations in optimized order // get the route when visiting all destinations in optimized order
InternalRouteResult route = InternalRouteResult route =
ComputeRoute(algorithms, snapped_phantoms, duration_trip, parameters.roundtrip); ComputeRoute(algorithms, snapped_phantoms, duration_trip, parameters.roundtrip, permit_private);
// get api response // get api response
const std::vector<std::vector<NodeID>> trips = {duration_trip}; const std::vector<std::vector<NodeID>> trips = {duration_trip};

View File

@ -68,6 +68,15 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
json_result); json_result);
} }
if (route_parameters.permit.size() > 0) {
if (route_parameters.permit.size() > 1) {
return Error("InvalidValue", "Invalid numer of permit values - only 1 allowed.", json_result);
}
if (route_parameters.permit.front() != "private") {
return Error("InvalidValue", "Invalid permit value.", json_result);
}
}
if (!CheckAllCoordinates(route_parameters.coordinates)) if (!CheckAllCoordinates(route_parameters.coordinates))
{ {
return Error("InvalidValue", "Invalid coordinate value.", json_result); return Error("InvalidValue", "Invalid coordinate value.", json_result);
@ -107,6 +116,8 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
(route_parameters.alternatives || route_parameters.number_of_alternatives > 0); (route_parameters.alternatives || route_parameters.number_of_alternatives > 0);
const auto number_of_alternatives = std::max(1u, route_parameters.number_of_alternatives); const auto number_of_alternatives = std::max(1u, route_parameters.number_of_alternatives);
const bool permit_private = route_parameters.permit.size() == 1 && route_parameters.permit.front() == "private";
// Alternatives do not support vias, only direct s,t queries supported // Alternatives do not support vias, only direct s,t queries supported
// See the implementation notes and high-level outline. // See the implementation notes and high-level outline.
// https://github.com/Project-OSRM/osrm-backend/issues/3905 // https://github.com/Project-OSRM/osrm-backend/issues/3905
@ -116,11 +127,11 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
} }
else if (1 == start_end_nodes.size() && algorithms.HasDirectShortestPathSearch()) else if (1 == start_end_nodes.size() && algorithms.HasDirectShortestPathSearch())
{ {
routes = algorithms.DirectShortestPathSearch(start_end_nodes.front()); routes = algorithms.DirectShortestPathSearch(start_end_nodes.front(), permit_private);
} }
else else
{ {
routes = algorithms.ShortestPathSearch(start_end_nodes, route_parameters.continue_straight); routes = algorithms.ShortestPathSearch(start_end_nodes, route_parameters.continue_straight, permit_private);
} }
// The post condition for all path searches is we have at least one route in our result. // The post condition for all path searches is we have at least one route in our result.

View File

@ -159,7 +159,8 @@ void computeWeightAndSharingOfViaPath(SearchEngineData<Algorithm> &engine_workin
EdgeWeight *real_weight_of_via_path, EdgeWeight *real_weight_of_via_path,
EdgeWeight *sharing_of_via_path, EdgeWeight *sharing_of_via_path,
const std::vector<NodeID> &packed_shortest_path, const std::vector<NodeID> &packed_shortest_path,
const EdgeWeight min_edge_offset) const EdgeWeight min_edge_offset,
const bool permit_private)
{ {
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes()); engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
@ -187,7 +188,8 @@ void computeWeightAndSharingOfViaPath(SearchEngineData<Algorithm> &engine_workin
upper_bound_s_v_path_weight, upper_bound_s_v_path_weight,
min_edge_offset, min_edge_offset,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS); DO_NOT_FORCE_LOOPS,
permit_private);
} }
// compute path <v,..,t> by reusing backward search from node t // compute path <v,..,t> by reusing backward search from node t
NodeID v_t_middle = SPECIAL_NODEID; NodeID v_t_middle = SPECIAL_NODEID;
@ -202,7 +204,8 @@ void computeWeightAndSharingOfViaPath(SearchEngineData<Algorithm> &engine_workin
upper_bound_of_v_t_path_weight, upper_bound_of_v_t_path_weight,
min_edge_offset, min_edge_offset,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS); DO_NOT_FORCE_LOOPS,
permit_private);
} }
*real_weight_of_via_path = upper_bound_s_v_path_weight + upper_bound_of_v_t_path_weight; *real_weight_of_via_path = upper_bound_s_v_path_weight + upper_bound_of_v_t_path_weight;
@ -328,7 +331,8 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
EdgeWeight *weight_of_via_path, EdgeWeight *weight_of_via_path,
NodeID *s_v_middle, NodeID *s_v_middle,
NodeID *v_t_middle, NodeID *v_t_middle,
const EdgeWeight min_edge_offset) const EdgeWeight min_edge_offset,
const bool permit_private)
{ {
new_forward_heap.Clear(); new_forward_heap.Clear();
new_reverse_heap.Clear(); new_reverse_heap.Clear();
@ -348,7 +352,8 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
upper_bound_s_v_path_weight, upper_bound_s_v_path_weight,
min_edge_offset, min_edge_offset,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS); DO_NOT_FORCE_LOOPS,
permit_private);
} }
if (INVALID_EDGE_WEIGHT == upper_bound_s_v_path_weight) if (INVALID_EDGE_WEIGHT == upper_bound_s_v_path_weight)
@ -369,7 +374,8 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
upper_bound_of_v_t_path_weight, upper_bound_of_v_t_path_weight,
min_edge_offset, min_edge_offset,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS); DO_NOT_FORCE_LOOPS,
permit_private);
} }
if (INVALID_EDGE_WEIGHT == upper_bound_of_v_t_path_weight) if (INVALID_EDGE_WEIGHT == upper_bound_of_v_t_path_weight)
@ -542,7 +548,8 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
upper_bound, upper_bound,
min_edge_offset, min_edge_offset,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS); DO_NOT_FORCE_LOOPS,
permit_private);
} }
if (!reverse_heap3.Empty()) if (!reverse_heap3.Empty())
{ {
@ -553,7 +560,8 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
upper_bound, upper_bound,
min_edge_offset, min_edge_offset,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS); DO_NOT_FORCE_LOOPS,
permit_private);
} }
} }
return (upper_bound <= t_test_path_weight); return (upper_bound <= t_test_path_weight);
@ -757,7 +765,8 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
&weight_of_via_path, &weight_of_via_path,
&sharing_of_via_path, &sharing_of_via_path,
packed_shortest_path, packed_shortest_path,
min_edge_offset); min_edge_offset,
routing_algorithms::AVOID_PRIVATE); // danpat TODO: parameterize this
const EdgeWeight maximum_allowed_sharing = const EdgeWeight maximum_allowed_sharing =
static_cast<EdgeWeight>(upper_bound_to_shortest_path_weight * VIAPATH_GAMMA); static_cast<EdgeWeight>(upper_bound_to_shortest_path_weight * VIAPATH_GAMMA);
if (sharing_of_via_path <= maximum_allowed_sharing && if (sharing_of_via_path <= maximum_allowed_sharing &&
@ -784,7 +793,8 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
&weight_of_via_path, &weight_of_via_path,
&s_v_middle, &s_v_middle,
&v_t_middle, &v_t_middle,
min_edge_offset)) min_edge_offset,
routing_algorithms::AVOID_PRIVATE)) // danpat TODO: parameterize permit_private
{ {
// select first admissable // select first admissable
selected_via_node = candidate.node; selected_via_node = candidate.node;

View File

@ -19,7 +19,8 @@ namespace routing_algorithms
template <> template <>
InternalRouteResult directShortestPathSearch(SearchEngineData<ch::Algorithm> &engine_working_data, InternalRouteResult directShortestPathSearch(SearchEngineData<ch::Algorithm> &engine_working_data,
const DataFacade<ch::Algorithm> &facade, const DataFacade<ch::Algorithm> &facade,
const PhantomNodes &phantom_nodes) const PhantomNodes &phantom_nodes,
const bool permit_private)
{ {
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes()); engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
auto &forward_heap = *engine_working_data.forward_heap_1; auto &forward_heap = *engine_working_data.forward_heap_1;
@ -39,7 +40,9 @@ InternalRouteResult directShortestPathSearch(SearchEngineData<ch::Algorithm> &en
packed_leg, packed_leg,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
phantom_nodes); phantom_nodes,
MAXIMAL_EDGE_WEIGHT,
permit_private);
std::vector<NodeID> unpacked_nodes; std::vector<NodeID> unpacked_nodes;
std::vector<EdgeID> unpacked_edges; std::vector<EdgeID> unpacked_edges;
@ -66,7 +69,8 @@ InternalRouteResult directShortestPathSearch(SearchEngineData<ch::Algorithm> &en
template <> template <>
InternalRouteResult directShortestPathSearch(SearchEngineData<mld::Algorithm> &engine_working_data, InternalRouteResult directShortestPathSearch(SearchEngineData<mld::Algorithm> &engine_working_data,
const DataFacade<mld::Algorithm> &facade, const DataFacade<mld::Algorithm> &facade,
const PhantomNodes &phantom_nodes) const PhantomNodes &phantom_nodes,
const bool /* permit_private */)
{ {
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes(), engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes(),
facade.GetMaxBorderNodeID() + 1); facade.GetMaxBorderNodeID() + 1);

View File

@ -244,7 +244,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
reverse_heap, reverse_heap,
prev_unbroken_timestamps_list[s].phantom_node, prev_unbroken_timestamps_list[s].phantom_node,
current_timestamps_list[s_prime].phantom_node, current_timestamps_list[s_prime].phantom_node,
weight_upper_bound); weight_upper_bound,
PERMIT_PRIVATE);
// get distance diff between loc1/2 and locs/s_prime // get distance diff between loc1/2 and locs/s_prime
const auto d_t = std::abs(network_distance - haversine_distance); const auto d_t = std::abs(network_distance - haversine_distance);

View File

@ -98,7 +98,8 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
const bool force_loop_forward, const bool force_loop_forward,
const bool force_loop_reverse, const bool force_loop_reverse,
const PhantomNodes & /*phantom_nodes*/, const PhantomNodes & /*phantom_nodes*/,
const EdgeWeight weight_upper_bound) const EdgeWeight weight_upper_bound,
const bool permit_private)
{ {
if (forward_heap.Empty() || reverse_heap.Empty()) if (forward_heap.Empty() || reverse_heap.Empty())
{ {
@ -127,7 +128,8 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
weight, weight,
min_edge_offset, min_edge_offset,
force_loop_forward, force_loop_forward,
force_loop_reverse); force_loop_reverse,
permit_private);
} }
if (!reverse_heap.Empty()) if (!reverse_heap.Empty())
{ {
@ -138,7 +140,8 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
weight, weight,
min_edge_offset, min_edge_offset,
force_loop_reverse, force_loop_reverse,
force_loop_forward); force_loop_forward,
permit_private);
} }
} }
@ -174,7 +177,8 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap, SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom, const PhantomNode &source_phantom,
const PhantomNode &target_phantom, const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound) EdgeWeight weight_upper_bound,
const bool permit_private)
{ {
forward_heap.Clear(); forward_heap.Clear();
reverse_heap.Clear(); reverse_heap.Clear();
@ -192,7 +196,8 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
DO_NOT_FORCE_LOOPS, DO_NOT_FORCE_LOOPS,
{source_phantom, target_phantom}, {source_phantom, target_phantom},
weight_upper_bound); weight_upper_bound,
permit_private);
if (weight == INVALID_EDGE_WEIGHT) if (weight == INVALID_EDGE_WEIGHT)
{ {

View File

@ -13,13 +13,15 @@ template InternalRouteResult
shortestPathSearch(SearchEngineData<ch::Algorithm> &engine_working_data, shortestPathSearch(SearchEngineData<ch::Algorithm> &engine_working_data,
const DataFacade<ch::Algorithm> &facade, const DataFacade<ch::Algorithm> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector, const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint); const boost::optional<bool> continue_straight_at_waypoint,
const bool permit_private);
template InternalRouteResult template InternalRouteResult
shortestPathSearch(SearchEngineData<mld::Algorithm> &engine_working_data, shortestPathSearch(SearchEngineData<mld::Algorithm> &engine_working_data,
const DataFacade<mld::Algorithm> &facade, const DataFacade<mld::Algorithm> &facade,
const std::vector<PhantomNodes> &phantom_nodes_vector, const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> continue_straight_at_waypoint); const boost::optional<bool> continue_straight_at_waypoint,
const bool permit_private);
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine