Skip to content

Commit

Permalink
Disable nodes with invalid segments
Browse files Browse the repository at this point in the history
oxidase authored and Patrick Niklaus committed May 11, 2017
1 parent a44b63f commit 9358aa1
Showing 9 changed files with 279 additions and 104 deletions.
163 changes: 163 additions & 0 deletions features/testbot/zero-speed-updates.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
Feature: Check zero speed updates

Scenario: Matching on restricted way, single segment
Given the query options
| geometries | geojson |
| annotations | true |

Given the node map
"""
a-1--b--c-2-d
"""

And the ways
| nodes |
| abcd |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
2,3,0
"""

When I match I should get
| trace | code |
| 12 | NoMatch |


Scenario: Matching restricted way, both segments
Given the node map
"""
a-1--b-2-c
"""

And the ways
| nodes | oneway |
| abc | no |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
2,3,0
3,2,0
"""

When I match I should get
| trace | code |
| 12 | NoMatch |


Scenario: Matching on restricted oneway
Given the node map
"""
a-1--b-2-c
"""

And the ways
| nodes | oneway |
| abc | yes |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
2,3,0
"""

When I match I should get
| trace | code |
| 12 | NoMatch |


Scenario: Routing on restricted way
Given the node map
"""
a-1-b-2-c
"""

And the ways
| nodes | oneway |
| abc | no |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
2,3,0
3,2,0
"""

When I route I should get
| from | to | code |
| 1 | 2 | NoRoute |


Scenario: Routing on restricted oneway
Given the node map
"""
a-1-b-2-c
"""

And the ways
| nodes | oneway |
| abc | yes |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
2,3,0
3,2,0
"""

When I route I should get
| from | to | bearings | code |
| 1 | 2 | 270 270 | NoRoute |


Scenario: Via routing on restricted oneway
Given the node map
"""
a-1-b-2-c-3-d
"""

And the ways
| nodes | oneway |
| abc | no |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
2,3,0
3,2,0
"""

When I route I should get
| waypoints | code |
| 1,2,3 | NoRoute |
| 3,2,1 | NoRoute |


@trip
Scenario: Trip
Given the node map
"""
a b
c d
"""

And the ways
| nodes |
| ab |
| bc |
| cb |
| da |
And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
1,2,0
2,1,0
"""

When I plan a trip I should get
| waypoints | trips | code |
| a,b,c,d | abcda | NoTrips |
| d,b,c,a | dbcad | NoTrips |
18 changes: 18 additions & 0 deletions include/engine/geospatial_query.hpp
Original file line number Diff line number Diff line change
@@ -416,6 +416,20 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_duration -= static_cast<EdgeDuration>(reverse_duration * ratio);
}

// check phantom node segments validity
auto areSegmentsValid = [](auto first, auto last) -> bool {
return std::find(first, last, INVALID_EDGE_WEIGHT) == last;
};
bool is_forward_valid_source =
areSegmentsValid(forward_weight_vector.begin(), forward_weight_vector.end());
bool is_forward_valid_target =
areSegmentsValid(forward_weight_vector.begin(),
forward_weight_vector.begin() + data.fwd_segment_position + 1);
bool is_reverse_valid_source =
areSegmentsValid(reverse_weight_vector.begin(), reverse_weight_vector.end());
bool is_reverse_valid_target = areSegmentsValid(
reverse_weight_vector.begin(), reverse_weight_vector.end() - data.fwd_segment_position);

auto transformed = PhantomNodeWithDistance{PhantomNode{data,
forward_weight,
reverse_weight,
@@ -425,6 +439,10 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_duration,
forward_duration_offset,
reverse_duration_offset,
is_forward_valid_source,
is_forward_valid_target,
is_reverse_valid_source,
is_reverse_valid_target,
point_on_segment,
input_coordinate},
current_perpendicular_distance};
72 changes: 37 additions & 35 deletions include/engine/phantom_node.hpp
Original file line number Diff line number Diff line change
@@ -46,37 +46,6 @@ namespace engine

struct PhantomNode
{
PhantomNode(SegmentID forward_segment_id,
SegmentID reverse_segment_id,
unsigned name_id,
EdgeWeight forward_weight,
EdgeWeight reverse_weight,
EdgeWeight forward_weight_offset,
EdgeWeight reverse_weight_offset,
EdgeWeight forward_duration,
EdgeWeight reverse_duration,
EdgeWeight forward_duration_offset,
EdgeWeight reverse_duration_offset,
unsigned packed_geometry_id_,
bool is_tiny_component,
unsigned component_id,
util::Coordinate location,
util::Coordinate input_location,
unsigned short fwd_segment_position,
extractor::TravelMode forward_travel_mode,
extractor::TravelMode backward_travel_mode)
: forward_segment_id(forward_segment_id), reverse_segment_id(reverse_segment_id),
name_id(name_id), forward_weight(forward_weight), reverse_weight(reverse_weight),
forward_weight_offset(forward_weight_offset),
reverse_weight_offset(reverse_weight_offset), forward_duration(forward_duration),
reverse_duration(reverse_duration), forward_duration_offset(forward_duration_offset),
reverse_duration_offset(reverse_duration_offset), packed_geometry_id(packed_geometry_id_),
component{component_id, is_tiny_component}, location(std::move(location)),
input_location(std::move(input_location)), fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode)
{
}

PhantomNode()
: forward_segment_id{SPECIAL_SEGMENTID, false},
reverse_segment_id{SPECIAL_SEGMENTID, false},
@@ -86,7 +55,9 @@ struct PhantomNode
forward_duration_offset(0), reverse_duration_offset(0),
packed_geometry_id(SPECIAL_GEOMETRYID), component{INVALID_COMPONENTID, false},
fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE), is_forward_valid_source(false),
is_forward_valid_target(false), is_reverse_valid_source(false),
is_reverse_valid_target(false)
{
}

@@ -134,6 +105,23 @@ struct PhantomNode

bool IsValid() const { return location.IsValid() && (name_id != INVALID_NAMEID); }

bool IsForwardValidSource() const
{
return forward_segment_id.enabled && is_forward_valid_source;
}
bool IsForwardValidTarget() const
{
return forward_segment_id.enabled && is_forward_valid_target;
}
bool IsReverseValidSource() const
{
return reverse_segment_id.enabled && is_reverse_valid_source;
}
bool IsReverseValidTarget() const
{
return reverse_segment_id.enabled && is_reverse_valid_target;
}

bool operator==(const PhantomNode &other) const { return location == other.location; }

template <class OtherT>
@@ -146,6 +134,10 @@ struct PhantomNode
EdgeWeight reverse_duration,
EdgeWeight forward_duration_offset,
EdgeWeight reverse_duration_offset,
bool is_forward_valid_source,
bool is_forward_valid_target,
bool is_reverse_valid_source,
bool is_reverse_valid_target,
const util::Coordinate location,
const util::Coordinate input_location)
: forward_segment_id{other.forward_segment_id},
@@ -159,7 +151,11 @@ struct PhantomNode
component{other.component.id, other.component.is_tiny}, location{location},
input_location{input_location}, fwd_segment_position{other.fwd_segment_position},
forward_travel_mode{other.forward_travel_mode},
backward_travel_mode{other.backward_travel_mode}
backward_travel_mode{other.backward_travel_mode},
is_forward_valid_source{is_forward_valid_source},
is_forward_valid_target{is_forward_valid_target},
is_reverse_valid_source{is_reverse_valid_source},
is_reverse_valid_target{is_reverse_valid_target}
{
}

@@ -187,8 +183,14 @@ struct PhantomNode
unsigned short fwd_segment_position;
// note 4 bits would suffice for each,
// but the saved byte would be padding anyway
extractor::TravelMode forward_travel_mode;
extractor::TravelMode backward_travel_mode;
extractor::TravelMode forward_travel_mode : 4;
extractor::TravelMode backward_travel_mode : 4;
// is phantom node valid to be used as source or target
private:
bool is_forward_valid_source : 1;
bool is_forward_valid_target : 1;
bool is_reverse_valid_source : 1;
bool is_reverse_valid_target : 1;
};

static_assert(sizeof(PhantomNode) == 72, "PhantomNode has more padding then expected");
57 changes: 33 additions & 24 deletions include/engine/routing_algorithms/routing_base.hpp
Original file line number Diff line number Diff line change
@@ -41,41 +41,23 @@ bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &targ

bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom);

template <bool DIRECTION, typename Heap>
void insertNodesInHeap(Heap &heap, const PhantomNode &phantom_node)
{
BOOST_ASSERT(phantom_node.IsValid());

const auto weight_sign = DIRECTION == FORWARD_DIRECTION ? -1 : 1;
if (phantom_node.forward_segment_id.enabled)
{
heap.Insert(phantom_node.forward_segment_id.id,
weight_sign * phantom_node.GetForwardWeightPlusOffset(),
phantom_node.forward_segment_id.id);
}
if (phantom_node.reverse_segment_id.enabled)
{
heap.Insert(phantom_node.reverse_segment_id.id,
weight_sign * phantom_node.GetReverseWeightPlusOffset(),
phantom_node.reverse_segment_id.id);
}
}

template <bool DIRECTION>
void insertNodesInHeap(SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap,
const PhantomNode &phantom_node)
{
BOOST_ASSERT(phantom_node.IsValid());

const auto weight_sign = DIRECTION == FORWARD_DIRECTION ? -1 : 1;
if (phantom_node.forward_segment_id.enabled)
if ((DIRECTION == FORWARD_DIRECTION && phantom_node.IsForwardValidSource()) ||
(DIRECTION == REVERSE_DIRECTION && phantom_node.IsForwardValidTarget()))
{
heap.Insert(
phantom_node.forward_segment_id.id,
weight_sign * phantom_node.GetForwardWeightPlusOffset(),
{phantom_node.forward_segment_id.id, weight_sign * phantom_node.GetForwardDuration()});
}
if (phantom_node.reverse_segment_id.enabled)
if ((DIRECTION == FORWARD_DIRECTION && phantom_node.IsReverseValidSource()) ||
(DIRECTION == REVERSE_DIRECTION && phantom_node.IsReverseValidTarget()))
{
heap.Insert(
phantom_node.reverse_segment_id.id,
@@ -87,8 +69,35 @@ void insertNodesInHeap(SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &hea
template <typename Heap>
void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes)
{
insertNodesInHeap<FORWARD_DIRECTION>(forward_heap, nodes.source_phantom);
insertNodesInHeap<REVERSE_DIRECTION>(reverse_heap, nodes.target_phantom);
const auto &source = nodes.source_phantom;
if (source.IsForwardValidSource())
{
forward_heap.Insert(source.forward_segment_id.id,
-source.GetForwardWeightPlusOffset(),
source.forward_segment_id.id);
}

if (source.IsReverseValidSource())
{
forward_heap.Insert(source.reverse_segment_id.id,
-source.GetReverseWeightPlusOffset(),
source.reverse_segment_id.id);
}

const auto &target = nodes.target_phantom;
if (target.IsForwardValidTarget())
{
reverse_heap.Insert(target.forward_segment_id.id,
target.GetForwardWeightPlusOffset(),
target.forward_segment_id.id);
}

if (target.IsReverseValidTarget())
{
reverse_heap.Insert(target.reverse_segment_id.id,
target.GetReverseWeightPlusOffset(),
target.reverse_segment_id.id);
}
}

template <typename FacadeT>
Loading

0 comments on commit 9358aa1

Please sign in to comment.