Filter out edges that have any speed=0 segments.
They become non-snappable and non-routable. Note that a single segment of speed=0 will eliminate the entire edge.
This commit is contained in:
committed by
Patrick Niklaus
parent
eda6d9dc7c
commit
d012b44b7f
@@ -20,6 +20,11 @@ namespace osrm
|
||||
namespace engine
|
||||
{
|
||||
|
||||
inline std::pair<bool, bool> boolPairAnd(const std::pair<bool, bool> &A, const std::pair<bool, bool> &B)
|
||||
{
|
||||
return std::make_pair(A.first && B.first, A.second && B.second);
|
||||
}
|
||||
|
||||
// Implements complex queries on top of an RTree and builds PhantomNodes from it.
|
||||
//
|
||||
// Only holds a weak reference on the RTree and coordinates!
|
||||
@@ -48,7 +53,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[](const CandidateSegment &) { return std::make_pair(true, true); },
|
||||
[this](const CandidateSegment &segment) { return HasValidEdge(segment); },
|
||||
[this, max_distance, input_coordinate](const std::size_t,
|
||||
const CandidateSegment &segment) {
|
||||
return CheckSegmentDistance(input_coordinate, segment, max_distance);
|
||||
@@ -68,7 +73,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[this, bearing, bearing_range, max_distance](const CandidateSegment &segment) {
|
||||
return CheckSegmentBearing(segment, bearing, bearing_range);
|
||||
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),HasValidEdge(segment));
|
||||
},
|
||||
[this, max_distance, input_coordinate](const std::size_t,
|
||||
const CandidateSegment &segment) {
|
||||
@@ -89,7 +94,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[this, bearing, bearing_range](const CandidateSegment &segment) {
|
||||
return CheckSegmentBearing(segment, bearing, bearing_range);
|
||||
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
|
||||
},
|
||||
[max_results](const std::size_t num_results, const CandidateSegment &) {
|
||||
return num_results >= max_results;
|
||||
@@ -111,7 +116,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[this, bearing, bearing_range](const CandidateSegment &segment) {
|
||||
return CheckSegmentBearing(segment, bearing, bearing_range);
|
||||
return boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
|
||||
},
|
||||
[this, max_distance, max_results, input_coordinate](
|
||||
const std::size_t num_results, const CandidateSegment &segment) {
|
||||
@@ -129,7 +134,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[](const CandidateSegment &) { return std::make_pair(true, true); },
|
||||
[this](const CandidateSegment &segment) { return HasValidEdge(segment); },
|
||||
[max_results](const std::size_t num_results, const CandidateSegment &) {
|
||||
return num_results >= max_results;
|
||||
});
|
||||
@@ -146,7 +151,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[](const CandidateSegment &) { return std::make_pair(true, true); },
|
||||
[this](const CandidateSegment &segment) { return HasValidEdge(segment); },
|
||||
[this, max_distance, max_results, input_coordinate](
|
||||
const std::size_t num_results, const CandidateSegment &segment) {
|
||||
return num_results >= max_results ||
|
||||
@@ -166,14 +171,18 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
bool has_big_component = false;
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[&has_big_component, &has_small_component](const CandidateSegment &segment) {
|
||||
[this, &has_big_component, &has_small_component](const CandidateSegment &segment) {
|
||||
auto use_segment = (!has_small_component ||
|
||||
(!has_big_component && !segment.data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
const auto valid_edges = HasValidEdge(segment);
|
||||
|
||||
has_big_component = has_big_component || !segment.data.component.is_tiny;
|
||||
has_small_component = has_small_component || segment.data.component.is_tiny;
|
||||
|
||||
if (valid_edges.first || valid_edges.second)
|
||||
{
|
||||
has_big_component = has_big_component || !segment.data.component.is_tiny;
|
||||
has_small_component = has_small_component || segment.data.component.is_tiny;
|
||||
}
|
||||
use_directions = boolPairAnd(use_directions, valid_edges);
|
||||
return use_directions;
|
||||
},
|
||||
[this, &has_big_component, max_distance, input_coordinate](
|
||||
@@ -201,14 +210,21 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
bool has_big_component = false;
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[&has_big_component, &has_small_component](const CandidateSegment &segment) {
|
||||
[this, &has_big_component, &has_small_component](const CandidateSegment &segment) {
|
||||
auto use_segment = (!has_small_component ||
|
||||
(!has_big_component && !segment.data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
if (!use_directions.first && !use_directions.second) return use_directions;
|
||||
const auto valid_edges = HasValidEdge(segment);
|
||||
|
||||
has_big_component = has_big_component || !segment.data.component.is_tiny;
|
||||
has_small_component = has_small_component || segment.data.component.is_tiny;
|
||||
if (valid_edges.first || valid_edges.second)
|
||||
{
|
||||
|
||||
has_big_component = has_big_component || !segment.data.component.is_tiny;
|
||||
has_small_component = has_small_component || segment.data.component.is_tiny;
|
||||
}
|
||||
|
||||
use_directions = boolPairAnd(use_directions, valid_edges);
|
||||
return use_directions;
|
||||
},
|
||||
[&has_big_component](const std::size_t num_results, const CandidateSegment &) {
|
||||
@@ -239,10 +255,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
auto use_segment = (!has_small_component ||
|
||||
(!has_big_component && !segment.data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
|
||||
|
||||
if (use_segment)
|
||||
{
|
||||
use_directions = CheckSegmentBearing(segment, bearing, bearing_range);
|
||||
use_directions = boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
|
||||
if (use_directions.first || use_directions.second)
|
||||
{
|
||||
has_big_component = has_big_component || !segment.data.component.is_tiny;
|
||||
@@ -283,10 +300,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
auto use_segment = (!has_small_component ||
|
||||
(!has_big_component && !segment.data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
use_directions = boolPairAnd(use_directions, HasValidEdge(segment));
|
||||
|
||||
if (use_segment)
|
||||
{
|
||||
use_directions = CheckSegmentBearing(segment, bearing, bearing_range);
|
||||
use_directions = boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range), HasValidEdge(segment));
|
||||
if (use_directions.first || use_directions.second)
|
||||
{
|
||||
has_big_component = has_big_component || !segment.data.component.is_tiny;
|
||||
@@ -440,6 +458,47 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
return std::make_pair(forward_bearing_valid, backward_bearing_valid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the edge weights are valid. We might have an edge,
|
||||
* but a traffic update might set the speed to 0 (weight == INVALID_EDGE_WEIGHT).
|
||||
* which means that this edge is not currently traversible. If this is the case,
|
||||
* then we shouldn't snap to this edge.
|
||||
*/
|
||||
std::pair<bool, bool> HasValidEdge(const CandidateSegment &segment) const
|
||||
{
|
||||
|
||||
bool forward_edge_valid = false;
|
||||
bool reverse_edge_valid = false;
|
||||
|
||||
if (segment.data.forward_packed_geometry_id != SPECIAL_EDGEID)
|
||||
{
|
||||
std::vector<EdgeWeight> forward_weight_vector;
|
||||
datafacade.GetUncompressedWeights(segment.data.forward_packed_geometry_id,
|
||||
forward_weight_vector);
|
||||
|
||||
if (forward_weight_vector[segment.data.fwd_segment_position] != INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
forward_edge_valid = segment.data.forward_segment_id.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
if (segment.data.reverse_packed_geometry_id != SPECIAL_EDGEID)
|
||||
{
|
||||
std::vector<EdgeWeight> reverse_weight_vector;
|
||||
datafacade.GetUncompressedWeights(segment.data.reverse_packed_geometry_id,
|
||||
reverse_weight_vector);
|
||||
|
||||
BOOST_ASSERT(segment.data.fwd_segment_position < reverse_weight_vector.size());
|
||||
|
||||
if (reverse_weight_vector[reverse_weight_vector.size() - segment.data.fwd_segment_position - 1] != INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
reverse_edge_valid = segment.data.reverse_segment_id.enabled;
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(forward_edge_valid, reverse_edge_valid);
|
||||
}
|
||||
|
||||
const RTreeT &rtree;
|
||||
const CoordinateList &coordinates;
|
||||
DataFacadeT &datafacade;
|
||||
|
||||
Reference in New Issue
Block a user