Disable nodes with invalid segments

This commit is contained in:
Michael Krasnyk
2017-05-06 00:02:53 +02:00
committed by Patrick Niklaus
parent a44b63fbb9
commit 9358aa1128
9 changed files with 279 additions and 104 deletions
+18
View File
@@ -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};
+37 -35
View File
@@ -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");
@@ -41,26 +41,6 @@ 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)
@@ -68,14 +48,16 @@ void insertNodesInHeap(SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &hea
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>
@@ -190,6 +190,10 @@ search(SearchEngineData<Algorithm> &engine_working_data,
EdgeWeight weight_upper_bound,
Args... args)
{
if (forward_heap.Empty() || reverse_heap.Empty())
{
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
}
const auto &partition = facade.GetMultiLevelPartition();
@@ -387,7 +391,7 @@ getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const PhantomNodes phantom_nodes{source_phantom, target_phantom};
insertNodesInHeaps(forward_heap, reverse_heap, phantom_nodes);
EdgeWeight weight;
EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> unpacked_nodes;
std::vector<EdgeID> unpacked_edges;
std::tie(weight, unpacked_nodes, unpacked_edges) = search(engine_working_data,
@@ -400,7 +404,9 @@ getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
phantom_nodes);
if (weight == INVALID_EDGE_WEIGHT)
{
return std::numeric_limits<double>::max();
}
std::vector<PathData> unpacked_path;