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

contract edges with differing non-conditional access restrictions #4613

Merged
merged 22 commits into from Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6e1b34a
make shortcut logging more useful
nilsnolde Feb 24, 2024
0b36329
comment
nilsnolde Feb 24, 2024
7fd1f39
misplaced count
nilsnolde Feb 24, 2024
38ddaba
address review
nilsnolde Feb 24, 2024
f8d7e19
[skip ci] remove names and speed requirements from node contraction; …
nilsnolde Feb 24, 2024
5076216
changelog
nilsnolde Feb 24, 2024
a413d9a
bidir astar is having a problem with 2 shortcuts between the same nod…
nilsnolde Feb 25, 2024
09126a5
add failing test but put it disabled
nilsnolde Feb 25, 2024
4042e15
comment
nilsnolde Feb 25, 2024
39b9f30
roll back changes to name/pronunciation etc
nilsnolde Feb 25, 2024
9829369
remove names/pronunciations etc from shortcuts again
nilsnolde Feb 25, 2024
e7843d8
extend shortcut creation further by contracting over vast majority of…
nilsnolde Feb 27, 2024
d830e92
fix test for tile sizes
nilsnolde Feb 28, 2024
cfac7e7
add modes mask to the new shortcuts
nilsnolde Feb 29, 2024
7fe45cf
forgot a variable
nilsnolde Feb 29, 2024
6f17a57
modes should be added only for non-conditional restrictions
nilsnolde Mar 4, 2024
33a76fd
remove comment and update changelog
nilsnolde Mar 25, 2024
4a61b00
what happened there.. I think the rebasing tool tends to mess things …
nilsnolde Mar 25, 2024
2fd5d2e
Merge branch 'master' into nn-shortcuts-access-restrictions
nilsnolde Mar 27, 2024
86b14eb
Merge branch 'master' into nn-shortcuts-access-restrictions
nilsnolde Apr 2, 2024
1293811
Merge branch 'master' into nn-shortcuts-access-restrictions
nilsnolde Apr 3, 2024
6d91dea
Merge branch 'master' into nn-shortcuts-access-restrictions
nilsnolde Apr 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -61,6 +61,7 @@ CMakeLists.txt.user
.idea
/.tidytmp
vcpkg*/
*.log

# python
.venv
Expand Down
7 changes: 4 additions & 3 deletions CHANGELOG.md
Expand Up @@ -46,6 +46,9 @@
* FIXED: unidirectional_astar.cc doesn't work for date_time type = 2 #4652(https://github.com/valhalla/valhalla/issues/4652)
* FIXED: a few fixes around the routing algorithms [#4626](https://github.com/valhalla/valhalla/pull/4642)
* FIXED: no need to search for GDAL when building data [#4651](https://github.com/valhalla/valhalla/pull/4651)
* FIXED: Fix segfault in OSRM serializer with bannerInstructions when destination is on roundabout [#4480](https://github.com/valhalla/valhalla/pull/4481)
* FIXED: Fix segfault in costmatrix (date_time and time zone always added). [#4530](https://github.com/valhalla/valhalla/pull/4530)
* FIXED: Fixed roundoff issue in Tiles Row and Col methods [#4585](https://github.com/valhalla/valhalla/pull/4585)
* **Enhancement**
* UPDATED: French translations, thanks to @xlqian [#4159](https://github.com/valhalla/valhalla/pull/4159)
* CHANGED: -j flag for multithreaded executables to override mjolnir.concurrency [#4168](https://github.com/valhalla/valhalla/pull/4168)
Expand Down Expand Up @@ -85,7 +88,6 @@
* UPDATED: updated country access overrides [#4460](https://github.com/valhalla/valhalla/pull/4460)
* CHANGED: date_time refactor as a preparation to return DST/timezone related offset in the response [#4365](https://github.com/valhalla/valhalla/pull/4365)
* ADDED: find connection on backward search for bidir matrix algo [#4329](https://github.com/valhalla/valhalla/pull/4329)
* FIXED: Fix segfault in OSRM serializer with bannerInstructions when destination is on roundabout [#4480](https://github.com/valhalla/valhalla/pull/4481)
* CHANGED: Adjustment of walk speed when walking on slight downhill [#4302](https://github.com/valhalla/valhalla/pull/4302)
* CHANGED: Do not reclassify ferry connections when no hierarchies are to be generated [#4487](https://github.com/valhalla/valhalla/pull/4487)
* ADDED: Added a config option to sort nodes spatially during graph building [#4455](https://github.com/valhalla/valhalla/pull/4455)
Expand All @@ -94,21 +96,20 @@
* CHANGED: use pkg-config to find spatialite & geos and remove our cmake modules; upgraded conan's boost to 1.83.0 in the process [#4253](https://github.com/valhalla/valhalla/pull/4253)
* ADDED: Added aggregation logic to filter stage of tile building [#4512](https://github.com/valhalla/valhalla/pull/4512)
* UPDATED: tz to 2023d [#4519](https://github.com/valhalla/valhalla/pull/4519)
* FIXED: Fix segfault in costmatrix (date_time and time zone always added). [#4530](https://github.com/valhalla/valhalla/pull/4530)
* CHANGED: libvalhalla.pc generation to have finer controls; install third_party public headers; overhaul lots of CMake; remove conan support [#4516](https://github.com/valhalla/valhalla/pull/4516)
* CHANGED: refactored matrix code to include a base class for all matrix algorithms to prepare for second passes on matrix [#4535](https://github.com/valhalla/valhalla/pull/4535)
* ADDED: matrix second pass for connections not found in the first pass, analogous to /route [#4536](https://github.com/valhalla/valhalla/pull/4536)
* UPDATED: cxxopts to 3.1.1 [#4541](https://github.com/valhalla/valhalla/pull/4541)
* CHANGED: make use of vendored libraries optional (other than libraries which are not commonly in package managers or only used for testing) [#4544](https://github.com/valhalla/valhalla/pull/4544)
* ADDED: Improved instructions for blind users [#3694](https://github.com/valhalla/valhalla/pull/3694)
* FIXED: Fixed roundoff issue in Tiles Row and Col methods [#4585](https://github.com/valhalla/valhalla/pull/4585)
* ADDED: isochrone proper polygon support & pbf output for isochrone [#4575](https://github.com/valhalla/valhalla/pull/4575)
* ADDED: return isotile grid as geotiff [#4594](https://github.com/valhalla/valhalla/pull/4594)
* ADDED: `ignore_non_vehicular_restrictions` parameter for truck costing [#4606](https://github.com/valhalla/valhalla/pull/4606)
* UPDATED: tz database to 2024a [#4643](https://github.com/valhalla/valhalla/pull/4643)
* ADDED: `hgv_no_penalty` costing option to allow penalized truck access to `hgv=no` edges [#4650](https://github.com/valhalla/valhalla/pull/4650)
* CHANGED: Significantly improve performance of graphbuilder [#4669](https://github.com/valhalla/valhalla/pull/4669)
* UPDATED: Improved turn by turn api reference documentation [#4675](https://github.com/valhalla/valhalla/pull/4675)
* CHANGED: contract nodes if connecting edges have different names or speed or non-conditional access restrictions [#4613](https://github.com/valhalla/valhalla/pull/4613)

## Release Date: 2023-05-11 Valhalla 3.4.0
* **Removed**
Expand Down
4 changes: 2 additions & 2 deletions src/mjolnir/restrictionbuilder.cc
Expand Up @@ -270,8 +270,8 @@ ComplexRestrictionBuilder CreateComplexRestriction(const OSMRestriction& restric
};

struct Result {
uint32_t forward_restrictions_count;
uint32_t reverse_restrictions_count;
uint32_t forward_restrictions_count = 0;
uint32_t reverse_restrictions_count = 0;
Comment on lines +273 to +274
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to initialize it, further down we only add to it. resulted in bogus restriction counts for the first level

std::vector<ComplexRestrictionBuilder> restrictions;
std::unordered_set<GraphId> part_of_restriction;
};
Expand Down
119 changes: 76 additions & 43 deletions src/mjolnir/shortcutbuilder.cc
Expand Up @@ -29,6 +29,50 @@ using namespace valhalla::mjolnir;

namespace {

struct ShortcutAccessRestriction {
std::unordered_map<AccessType, AccessRestriction> all_restrictions;
// important to set the edge's attribute
uint64_t modes = 0;

ShortcutAccessRestriction(const std::vector<AccessRestriction>&& restrictions) {
for (const auto& res : restrictions) {
modes |= res.modes();
all_restrictions.emplace(res.type(), std::move(res));
}
};

// updates non-conditional restrictions if their value is lower than the current value
// TODO(nils): we could also contract over conditional restrictions with a bit more work:
// kTimeDenied is fine to just append all restrictions of the base edges, but kTimeAllowed
// will be harder, there we'll have to merge overlapping time periods
void update_nonconditional(const std::vector<AccessRestriction>&& other_restrictions) {
for (const auto& new_ar : other_restrictions) {
// update the modes for the edge attribute regardless
if (new_ar.type() == AccessType::kTimedAllowed || new_ar.type() == AccessType::kTimedDenied ||
new_ar.type() == AccessType::kDestinationAllowed) {
continue;
}
modes |= new_ar.modes();
Comment on lines +51 to +55
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did this small change to not record modes of restrictions we don't care about

auto ar_inserted = all_restrictions.emplace(new_ar.type(), new_ar);
if (!ar_inserted.second && new_ar.value() < ar_inserted.first->second.value()) {
ar_inserted.first->second = std::move(new_ar);
}
}
}
};

// only keeps access restrictions which can fail contraction
void remove_nonconditional_restrictions(std::vector<AccessRestriction>& access_restrictions) {
access_restrictions.erase(std::remove_if(std::begin(access_restrictions),
std::end(access_restrictions),
[](const AccessRestriction& elem) {
return elem.type() != AccessType::kDestinationAllowed &&
elem.type() != AccessType::kTimedAllowed &&
elem.type() != AccessType::kTimedDenied;
}),
std::end(access_restrictions));
}

// Simple structure to hold the 2 pair of directed edges at a node.
// First edge in the pair is incoming and second is outgoing
struct EdgePairs {
Expand Down Expand Up @@ -59,9 +103,9 @@ bool EdgesMatch(const graph_tile_ptr& tile, const DirectedEdge* edge1, const Dir
return false;
}

// Neither edge can be part of a complex turn restriction or differ on access restrictions
// Neither edge can be part of a complex turn restriction
if (edge1->start_restriction() || edge1->end_restriction() || edge2->start_restriction() ||
edge2->end_restriction() || edge1->access_restriction() != edge2->access_restriction()) {
edge2->end_restriction()) {
return false;
}

Expand All @@ -77,20 +121,12 @@ bool EdgesMatch(const graph_tile_ptr& tile, const DirectedEdge* edge1, const Dir
return false;
}

// Names must match
// TODO - this allows matches in any order. Do we need to maintain order?
// TODO - should allow near matches?
std::vector<std::string> edge1names = tile->GetNames(edge1);
std::vector<std::string> edge2names = tile->GetNames(edge2);
std::sort(edge1names.begin(), edge1names.end());
std::sort(edge2names.begin(), edge2names.end());
if (edge1names != edge2names)
return false;

// if they have access restrictions those must match (for modes that use shortcuts)
if (edge1->access_restriction()) {
// if there's conditional access restrictions, they must match; others we can safely contract over
if (edge1->access_restriction() || edge2->access_restriction()) {
auto res1 = tile->GetAccessRestrictions(edge1 - tile->directededge(0), kVehicularAccess);
remove_nonconditional_restrictions(res1);
auto res2 = tile->GetAccessRestrictions(edge2 - tile->directededge(0), kVehicularAccess);
remove_nonconditional_restrictions(res2);
if (res1.size() != res2.size())
return false;
for (size_t i = 0; i < res1.size(); ++i) {
Expand Down Expand Up @@ -231,11 +267,6 @@ bool CanContract(GraphReader& reader,
return false;
}

// Can not have different speeds in the same direction
if ((oppdiredge1->speed() != edge2->speed()) || (oppdiredge2->speed() != edge1->speed())) {
return false;
}

// ISO country codes at the end nodes must equal this node
std::string iso = tile->admininfo(nodeinfo->admin_index()).country_iso();
std::string e1_iso = EndNodeIso(edge1, reader);
Expand Down Expand Up @@ -280,7 +311,8 @@ void ConnectEdges(GraphReader& reader,
uint32_t& restrictions,
float& average_density,
float& total_duration,
float& total_truck_duration) {
float& total_truck_duration,
ShortcutAccessRestriction& access_restrictions) {
// Get the tile and directed edge.
auto tile = reader.GetGraphTile(startnode);
const DirectedEdge* directededge = tile->directededge(edgeid);
Expand Down Expand Up @@ -324,6 +356,9 @@ void ConnectEdges(GraphReader& reader,
// Add to the weighted average
average_density += directededge->length() * directededge->density();

// Preserve the most restrictive access restrictions
access_restrictions.update_nonconditional(tile->GetAccessRestrictions(edgeid.id(), kAllAccess));

// Update the end node
endnode = directededge->endnode();
}
Expand Down Expand Up @@ -403,22 +438,10 @@ std::pair<uint32_t, uint32_t> AddShortcutEdges(GraphReader& reader,
std::reverse(shape.begin(), shape.end());
}

// Get names - they apply over all edges of the shortcut
auto names = edgeinfo.GetNames();
auto tagged_values = edgeinfo.GetTaggedValues();
auto linguistics = edgeinfo.GetLinguisticTaggedValues();

auto types = edgeinfo.GetTypes();

// Add any access restriction records. We don't contract if they differ, so if
// there's any, they're the same for all involved edges
if (newedge.access_restriction()) {
auto restrictions = tile->GetAccessRestrictions(edge_id.id(), kAllAccess);
for (const auto& res : restrictions) {
tilebuilder.AddAccessRestriction(AccessRestriction(tilebuilder.directededges().size(),
res.type(), res.modes(), res.value()));
}
}
// store all access_restrictions of the base edge: non-conditional ones will be updated while
// contracting, conditional ones are breaking contraction and are safe to simply copy
ShortcutAccessRestriction access_restrictions{
tile->GetAccessRestrictions(edge_id.id(), kAllAccess)};

// Connect edges to the shortcut while the end node is marked as
// contracted (contains edge pairs in the shortcut info).
Expand Down Expand Up @@ -454,13 +477,10 @@ std::pair<uint32_t, uint32_t> AddShortcutEdges(GraphReader& reader,
// on the connected shortcut - need to set that so turn restrictions
// off of shortcuts work properly
ConnectEdges(reader, end_node, next_edge_id, shape, end_node, opp_local_idx, rst,
average_density, total_duration, total_truck_duration);
average_density, total_duration, total_truck_duration, access_restrictions);
total_edge_count++;
}

// Names can be different in the forward and backward direction
bool diff_names = tilebuilder.OpposingEdgeInfoDiffers(tile, directededge);

// Get the length from the shape. This prevents roundoff issues when forming
// elevation.
uint32_t length = valhalla::midgard::length(shape);
Expand All @@ -469,13 +489,14 @@ std::pair<uint32_t, uint32_t> AddShortcutEdges(GraphReader& reader,
// edge in case multiple shortcut edges exist between the 2 nodes.
// Test whether this shape is forward or reverse (in case an existing
// edge exists). Shortcuts use way Id = 0.Set mean elevation to 0 as a placeholder,
// set it later if adding elevation to this dataset.
// set it later if adding elevation to this dataset. No need for names etc, shortcuts
// aren't used in guidance
bool forward = true;
uint32_t idx = ((length & 0xfffff) | ((shape.size() & 0xfff) << 20));
uint32_t edge_info_offset =
tilebuilder.AddEdgeInfo(idx, start_node, end_node, 0, 0, edgeinfo.bike_network(),
edgeinfo.speed_limit(), shape, names, tagged_values, linguistics,
types, forward, diff_names);
edgeinfo.speed_limit(), shape, {}, {}, {}, 0, forward, false);
;

newedge.set_edgeinfo_offset(edge_info_offset);

Expand All @@ -489,6 +510,18 @@ std::pair<uint32_t, uint32_t> AddShortcutEdges(GraphReader& reader,
newedge.set_opp_local_idx(opp_local_idx);
newedge.set_restrictions(rst);

// add new access restrictions if any and set the mask on the edge
if (access_restrictions.all_restrictions.size()) {
newedge.set_access_restriction(access_restrictions.modes);
for (const auto& res : access_restrictions.all_restrictions) {
tilebuilder.AddAccessRestriction(AccessRestriction(tilebuilder.directededges().size(),
res.second.type(), res.second.modes(),
res.second.value()));
}
}

// set new access mask

// Update the length, curvature, and end node
newedge.set_length(length);
newedge.set_curvature(compute_curvature(shape));
Expand Down
81 changes: 78 additions & 3 deletions test/astar.cc
Expand Up @@ -1571,7 +1571,7 @@
)";
const gurka::ways ways = {
// make ABC to be a shortcut
{"ABC", {{"highway", "primary"}, {"maxspeed", "80"}}},
{"ABC", {{"highway", "motorway"}, {"maxspeed", "80"}}},
// make CDE to be a shortcut
{"CDE", {{"highway", "primary"}, {"maxspeed", "80"}}},
{"1A", {{"highway", "secondary"}}},
Expand All @@ -1580,8 +1580,8 @@
{"D5", {{"highway", "secondary"}}},
// set speeds less than on ABCDE path to force the algorithm
// to go through ABCDE nodes instead of AXY
{"AX", {{"highway", "primary"}, {"maxspeed", "70"}}},
{"XY", {{"highway", "primary"}, {"maxspeed", "70"}}},
{"AX", {{"highway", "motorway"}, {"maxspeed", "70"}}},
{"XY", {{"highway", "trunk"}, {"maxspeed", "70"}}},
{"YE", {{"highway", "primary"}, {"maxspeed", "80"}}},
{"E2", {{"highway", "secondary"}}},
};
Expand Down Expand Up @@ -1679,6 +1679,81 @@
}
}

// TODO(nils): this test fails currently, because bidir A* has a problem with 2 shortcuts between the
// same nodes: https://github.com/valhalla/valhalla/issues/4609
TEST(BiDiAstar, DISABLED_test_recost_path_failing) {
const std::string ascii_map = R"(

Check warning on line 1685 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1684-L1685

Added lines #L1684 - L1685 were not covered by tests
X-----------Y
/ \
1----A E---2
\ /
B--C--------D
)";
const gurka::ways ways = {
// make ABCDE to be a shortcut
{"ABC", {{"highway", "primary"}, {"maxspeed", "80"}}},
{"CDE", {{"highway", "primary"}, {"maxspeed", "80"}}},
{"1A", {{"highway", "secondary"}}},
// set speeds less than on ABCDE path to force the algorithm
// to go through ABCDE nodes instead of AXY
{"AX", {{"highway", "primary"}, {"maxspeed", "70"}}},
{"XY", {{"highway", "primary"}, {"maxspeed", "70"}}},
{"YE", {{"highway", "primary"}, {"maxspeed", "80"}}},
{"E2", {{"highway", "secondary"}}},
};

Check warning on line 1703 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1703

Added line #L1703 was not covered by tests

auto nodes = gurka::detail::map_to_coordinates(ascii_map, 500);

Check warning on line 1705 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1705

Added line #L1705 was not covered by tests

const std::string test_dir = "test/data/astar_shortcuts_recosting";
const auto map = gurka::buildtiles(nodes, ways, {}, {}, test_dir);

Check warning on line 1708 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1707-L1708

Added lines #L1707 - L1708 were not covered by tests

vb::GraphReader graphreader(map.config.get_child("mjolnir"));

Check warning on line 1710 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1710

Added line #L1710 was not covered by tests

// before continue check that ABC is actually a shortcut
const auto ABCDE = gurka::findEdgeByNodes(graphreader, nodes, "A", "E");
ASSERT_TRUE(std::get<1>(ABCDE)->is_shortcut()) << "Expected ABCDE to be a shortcut";

Check warning on line 1714 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1713-L1714

Added lines #L1713 - L1714 were not covered by tests

Options options;
create_costing_options(options, Costing::auto_);
vs::TravelMode travel_mode = vs::TravelMode::kDrive;
const auto mode_costing = vs::CostFactory().CreateModeCosting(options, travel_mode);

Check warning on line 1719 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1716-L1719

Added lines #L1716 - L1719 were not covered by tests

std::vector<vb::Location> locations;

Check warning on line 1721 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1721

Added line #L1721 was not covered by tests
// set origin location
locations.push_back({nodes["1"]});

Check warning on line 1723 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1723

Added line #L1723 was not covered by tests
// set destination location
locations.push_back({nodes["2"]});
auto pbf_locations = ToPBFLocations(locations, graphreader, mode_costing[int(travel_mode)]);

Check warning on line 1726 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1725-L1726

Added lines #L1725 - L1726 were not covered by tests

vt::BidirectionalAStar astar;

Check warning on line 1728 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1728

Added line #L1728 was not covered by tests

// hack hierarchy limits to allow to go through the shortcut
{
auto& hierarchy_limits =
mode_costing[int(travel_mode)]->GetHierarchyLimits(); // access mutable limits
for (auto& hierarchy : hierarchy_limits) {
hierarchy.Relax(0.f, 0.f);

Check warning on line 1735 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1733-L1735

Added lines #L1733 - L1735 were not covered by tests
}
}
const auto path =
astar.GetBestPath(pbf_locations[0], pbf_locations[1], graphreader, mode_costing, travel_mode)
.front();

Check warning on line 1740 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1739-L1740

Added lines #L1739 - L1740 were not covered by tests

// collect names of base edges
std::vector<std::string> expected_names = {"1A", "AB", "BC", "CD", "DE", "E2"};
std::vector<std::string> actual_names;
for (const auto& info : path) {
const auto* edge = graphreader.directededge(info.edgeid);
ASSERT_FALSE(edge->is_shortcut()) << "Final path shouldn't contain shortcuts";

Check warning on line 1747 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1743-L1747

Added lines #L1743 - L1747 were not covered by tests

const auto name = graphreader.edgeinfo(info.edgeid).GetNames()[0];
actual_names.emplace_back(name);
}

Check warning on line 1751 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1749-L1751

Added lines #L1749 - L1751 were not covered by tests
// TODO(nils): it gets the wrong path! bidir A* has a problem with 2 shortcuts between the same
// nodes
EXPECT_EQ(actual_names, expected_names);
}

Check warning on line 1755 in test/astar.cc

View check run for this annotation

Codecov / codecov/patch

test/astar.cc#L1754-L1755

Added lines #L1754 - L1755 were not covered by tests

class BiAstarTest : public thor::BidirectionalAStar {
public:
explicit BiAstarTest(const boost::property_tree::ptree& config = {}) : BidirectionalAStar(config) {
Expand Down
1 change: 1 addition & 0 deletions test/gurka/gurka.cc
Expand Up @@ -488,6 +488,7 @@ map buildtiles(const nodelayout& layout,
* @param end_node the node that should be the target of the directed edge you want
* @param tile_id optional tile_id to limit the search to
* @param way_id optional way_id to limit the search to
* @param is_shortcut whether we want a shortcut returned
* @return the directed edge that matches, or nullptr if there was no match
*/
std::tuple<const baldr::GraphId,
Expand Down