Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When matching, ignore 'is_startpoint' propert, snap to any edge #5297

Merged
merged 6 commits into from
Dec 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- Table:
- ADDED: new parameter `scale_factor` which will scale the cell `duration` values by this factor. [#5298](https://github.com/Project-OSRM/osrm-backend/pull/5298)
- FIXED: only trigger `scale_factor` code to scan matrix when necessary. [#5303](https://github.com/Project-OSRM/osrm-backend/pull/5303)
- Matching:
- CHANGED: matching will now consider edges marked with is_startpoint=false, allowing matching over ferries and other previously non-matchable edge types. [#5297](https://github.com/Project-OSRM/osrm-backend/pull/5297)

# 5.20.0
- Changes from 5.19.0:
Expand Down
1 change: 1 addition & 0 deletions docs/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ Vector tiles contain two layers:
| `weight ` | `integer` | how long this segment takes to traverse, in units (may differ from `duration` when artificial biasing is applied in the Lua profiles). ACTUAL ROUTING USES THIS VALUE. |
| `name` | `string` | the name of the road this segment belongs to |
| `rate` | `float` | the value of `length/weight` - analagous to `speed`, but using the `weight` value rather than `duration`, rounded to the nearest integer |
| `is_startpoint` | `boolean` | whether this segment can be used as a start/endpoint for routes |

`turns` layer:

Expand Down
9 changes: 9 additions & 0 deletions features/car/ferry.feature
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,12 @@ Feature: Car - Handle ferry routes
When I route I should get
| from | to | route | modes | time |
| c | d | bcde,bcde | ferry,ferry | 600s |

Given the query options
| geometries | geojson |
| overview | full |

# Note that matching *should* work across unsnappable ferries
When I match I should get
| trace | geometry | duration |
| abcdef| 1,1,1.000899,1,1.000899,1,1.002697,1,1.002697,1,1.003596,1,1.003596,1,1.005394,1,1.005394,1,1.006293,1 | 610.9 |
10 changes: 6 additions & 4 deletions include/engine/datafacade/contiguous_internalmem_datafacade.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,25 +312,27 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance,
const Approach approach) const override final
const Approach approach,
const bool use_all_edges) const override final
{
BOOST_ASSERT(m_geospatial_query.get());

return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, approach);
input_coordinate, max_distance, approach, use_all_edges);
}

std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance,
const int bearing,
const int bearing_range,
const Approach approach) const override final
const Approach approach,
const bool use_all_edges) const override final
{
BOOST_ASSERT(m_geospatial_query.get());

return m_geospatial_query->NearestPhantomNodesInRange(
input_coordinate, max_distance, bearing, bearing_range, approach);
input_coordinate, max_distance, bearing, bearing_range, approach, use_all_edges);
}

std::vector<PhantomNodeWithDistance>
Expand Down
6 changes: 4 additions & 2 deletions include/engine/datafacade/datafacade_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,13 @@ class BaseDataFacade
const float max_distance,
const int bearing,
const int bearing_range,
const Approach approach) const = 0;
const Approach approach,
const bool use_all_edges) const = 0;
virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const float max_distance,
const Approach approach) const = 0;
const Approach approach,
const bool use_all_edges) const = 0;

virtual std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const util::Coordinate input_coordinate,
Expand Down
24 changes: 16 additions & 8 deletions include/engine/geospatial_query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const util::Coordinate input_coordinate,
const double max_distance,
const Approach approach) const
const Approach approach,
const bool use_all_edges) const
{
auto results = rtree.Nearest(
input_coordinate,
[this, approach, &input_coordinate](const CandidateSegment &segment) {
return boolPairAnd(boolPairAnd(HasValidEdge(segment), CheckSegmentExclude(segment)),
CheckApproach(input_coordinate, segment, approach));
[this, approach, &input_coordinate, use_all_edges](const CandidateSegment &segment) {
return boolPairAnd(
boolPairAnd(HasValidEdge(segment, use_all_edges), CheckSegmentExclude(segment)),
CheckApproach(input_coordinate, segment, approach));
},
[this, max_distance, input_coordinate](const std::size_t,
const CandidateSegment &segment) {
Expand All @@ -76,15 +78,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const double max_distance,
const int bearing,
const int bearing_range,
const Approach approach) const
const Approach approach,
const bool use_all_edges) const
{
auto results = rtree.Nearest(
input_coordinate,
[this, approach, &input_coordinate, bearing, bearing_range](
[this, approach, &input_coordinate, bearing, bearing_range, use_all_edges](
const CandidateSegment &segment) {
auto use_direction =
boolPairAnd(CheckSegmentBearing(segment, bearing, bearing_range),
boolPairAnd(HasValidEdge(segment), CheckSegmentExclude(segment)));
boolPairAnd(HasValidEdge(segment, use_all_edges),
CheckSegmentExclude(segment)));
use_direction =
boolPairAnd(use_direction, CheckApproach(input_coordinate, segment, approach));
return use_direction;
Expand Down Expand Up @@ -628,7 +632,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
* 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
std::pair<bool, bool> HasValidEdge(const CandidateSegment &segment,
const bool use_all_edges = false) const
{

bool forward_edge_valid = false;
Expand All @@ -652,6 +657,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
reverse_edge_valid = data.reverse_segment_id.enabled;
}

forward_edge_valid = forward_edge_valid && (data.is_startpoint || use_all_edges);
reverse_edge_valid = reverse_edge_valid && (data.is_startpoint || use_all_edges);

return std::make_pair(forward_edge_valid, reverse_edge_valid);
}

Expand Down
8 changes: 5 additions & 3 deletions include/engine/plugins/plugin_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ class BasePlugin
std::vector<std::vector<PhantomNodeWithDistance>>
GetPhantomNodesInRange(const datafacade::BaseDataFacade &facade,
const api::BaseParameters &parameters,
const std::vector<double> radiuses) const
const std::vector<double> radiuses,
bool use_all_edges = false) const
{
std::vector<std::vector<PhantomNodeWithDistance>> phantom_nodes(
parameters.coordinates.size());
Expand Down Expand Up @@ -171,12 +172,13 @@ class BasePlugin
radiuses[i],
parameters.bearings[i]->bearing,
parameters.bearings[i]->range,
approach);
approach,
use_all_edges);
}
else
{
phantom_nodes[i] = facade.NearestPhantomNodesInRange(
parameters.coordinates[i], radiuses[i], approach);
parameters.coordinates[i], radiuses[i], approach, use_all_edges);
}
}

Expand Down
5 changes: 0 additions & 5 deletions include/extractor/edge_based_graph_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ class EdgeBasedGraphFactory
// The following get access functions destroy the content in the factory
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
Expand All @@ -112,10 +111,6 @@ class EdgeBasedGraphFactory
std::vector<ConditionalTurnPenalty>
IndexConditionals(std::vector<Conditional> &&conditionals) const;

//! maps index from m_edge_based_node_list to ture/false if the node is an entry point to the
//! graph
std::vector<bool> m_edge_based_node_is_startpoint;

//! node weights that indicate the length of the segment (node based) represented by the
//! edge-based node
std::vector<EdgeWeight> m_edge_based_node_weights;
Expand Down
12 changes: 8 additions & 4 deletions include/extractor/edge_based_node_segment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ struct EdgeBasedNodeSegment
EdgeBasedNodeSegment()
: forward_segment_id{SPECIAL_SEGMENTID, false},
reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), v(SPECIAL_NODEID),
fwd_segment_position(std::numeric_limits<unsigned short>::max())
fwd_segment_position(std::numeric_limits<unsigned short>::max() >>
1), // >> 1 because we've only got 15 bits
is_startpoint(false)
{
}

explicit EdgeBasedNodeSegment(const SegmentID forward_segment_id_,
const SegmentID reverse_segment_id_,
NodeID u,
NodeID v,
unsigned short fwd_segment_position)
unsigned short fwd_segment_position,
bool is_startpoint_)
: forward_segment_id(forward_segment_id_), reverse_segment_id(reverse_segment_id_), u(u),
v(v), fwd_segment_position(fwd_segment_position)
v(v), fwd_segment_position(fwd_segment_position), is_startpoint(is_startpoint_)
{
BOOST_ASSERT(forward_segment_id.enabled || reverse_segment_id.enabled);
}
Expand All @@ -41,7 +44,8 @@ struct EdgeBasedNodeSegment
SegmentID reverse_segment_id; // edge-based graph node ID in reverse direction (v->u if exists)
NodeID u; // node-based graph node ID of the start node
NodeID v; // node-based graph node ID of the target node
unsigned short fwd_segment_position; // segment id in a compressed geometry
unsigned short fwd_segment_position : 15; // segment id in a compressed geometry
bool is_startpoint : 1;
};
}
}
Expand Down
2 changes: 0 additions & 2 deletions include/extractor/extractor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ class Extractor
// output data
EdgeBasedNodeDataContainer &edge_based_nodes_container,
std::vector<EdgeBasedNodeSegment> &edge_based_node_segments,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
std::vector<EdgeDuration> &edge_based_node_durations,
std::vector<EdgeDistance> &edge_based_node_distances,
Expand All @@ -97,7 +96,6 @@ class Extractor
const std::vector<EdgeBasedNodeSegment> &input_node_segments,
EdgeBasedNodeDataContainer &nodes_container) const;
void BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments,
std::vector<bool> node_is_startpoint,
const std::vector<util::Coordinate> &coordinates);
std::shared_ptr<RestrictionMap> LoadRestrictionMap();

Expand Down
3 changes: 2 additions & 1 deletion src/engine/plugins/match.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
});
}

auto candidates_lists = GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses);
auto candidates_lists =
GetPhantomNodesInRange(facade, tidied.parameters, search_radiuses, true);

filterCandidates(tidied.parameters.coordinates, candidates_lists);
if (std::all_of(candidates_lists.begin(),
Expand Down
13 changes: 12 additions & 1 deletion src/engine/plugins/tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ struct SpeedLayer : public vtzero::layer_builder
vtzero::index_value key_duration;
vtzero::index_value key_name;
vtzero::index_value key_rate;
vtzero::index_value key_is_startpoint;

SpeedLayer(vtzero::tile_builder &tile)
: layer_builder(tile, "speeds"), uint_index(*this), double_index(*this),
Expand All @@ -302,7 +303,8 @@ struct SpeedLayer : public vtzero::layer_builder
key_datasource(add_key_without_dup_check("datasource")),
key_weight(add_key_without_dup_check("weight")),
key_duration(add_key_without_dup_check("duration")),
key_name(add_key_without_dup_check("name")), key_rate(add_key_without_dup_check("rate"))
key_name(add_key_without_dup_check("name")), key_rate(add_key_without_dup_check("rate")),
key_is_startpoint(add_key_without_dup_check("is_startpoint"))
{
}

Expand Down Expand Up @@ -349,6 +351,11 @@ class SpeedLayerFeatureBuilder : public vtzero::linestring_feature_builder

void set_rate(double value) { add_property(m_layer.key_rate, m_layer.double_index(value)); }

void set_is_startpoint(bool value)
{
add_property(m_layer.key_is_startpoint, m_layer.bool_index(value));
}

}; // class SpeedLayerFeatureBuilder

struct TurnsLayer : public vtzero::layer_builder
Expand Down Expand Up @@ -485,6 +492,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
const auto reverse_datasource_idx = reverse_datasource_range(
reverse_datasource_range.size() - edge.fwd_segment_position - 1);

const auto is_startpoint = edge.is_startpoint;

const auto component_id = facade.GetComponentID(edge.forward_segment_id.id);
const auto name_id = facade.GetNameIndex(edge.forward_segment_id.id);
auto name = facade.GetNameForID(name_id);
Expand Down Expand Up @@ -516,6 +525,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
fbuilder.set_duration(forward_duration / 10.0);
fbuilder.set_name(name);
fbuilder.set_rate(forward_rate / 10.0);
fbuilder.set_is_startpoint(is_startpoint);

fbuilder.commit();
}
Expand Down Expand Up @@ -549,6 +559,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
fbuilder.set_duration(reverse_duration / 10.0);
fbuilder.set_name(name);
fbuilder.set_rate(reverse_rate / 10.0);
fbuilder.set_is_startpoint(is_startpoint);

fbuilder.commit();
}
Expand Down
12 changes: 2 additions & 10 deletions src/extractor/edge_based_graph_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSe
swap(nodes, m_edge_based_node_segments);
}

void EdgeBasedGraphFactory::GetStartPointMarkers(std::vector<bool> &node_is_startpoint)
{
using std::swap; // Koenig swap
swap(m_edge_based_node_is_startpoint, node_is_startpoint);
}

void EdgeBasedGraphFactory::GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights)
{
using std::swap; // Koenig swap
Expand Down Expand Up @@ -229,10 +223,9 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
edge_id_to_segment_id(nbe_to_ebn_mapping[edge_id_2]),
current_edge_source_coordinate_id,
current_edge_target_coordinate_id,
i);
i,
forward_data.flags.startpoint || reverse_data.flags.startpoint);

m_edge_based_node_is_startpoint.push_back(forward_data.flags.startpoint ||
reverse_data.flags.startpoint);
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
}

Expand Down Expand Up @@ -427,7 +420,6 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
}
}

BOOST_ASSERT(m_edge_based_node_segments.size() == m_edge_based_node_is_startpoint.size());
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size());
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_durations.size());
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_distances.size());
Expand Down
Loading