Skip to content

Commit eff9dbb

Browse files
tracking: tracks an attribute for a path
works via labels + entry dijkstra updates entry tracking with the label tracking useful to know if a path contains an elevator somewhere without having to actually reconstruct the whole path
1 parent 6cf0a46 commit eff9dbb

File tree

8 files changed

+84
-58
lines changed

8 files changed

+84
-58
lines changed

include/osr/routing/dijkstra.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct dijkstra {
5757
cost_[neighbor.get_key()].update(
5858
l, neighbor, static_cast<cost_t>(total), curr)) {
5959
auto next = label{neighbor, static_cast<cost_t>(total)};
60-
next.track(r, way, neighbor.get_node());
60+
next.track(l, r, way, neighbor.get_node());
6161
pq_.push(std::move(next));
6262
}
6363
});

include/osr/routing/profiles/bike.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct bike {
3939
constexpr node get_node() const noexcept { return {n_}; }
4040
constexpr cost_t cost() const noexcept { return cost_; }
4141

42-
void track(ways::routing const&, way_idx_t, node_idx_t) {}
42+
void track(label const&, ways::routing const&, way_idx_t, node_idx_t) {}
4343

4444
node_idx_t n_;
4545
level_t lvl_;

include/osr/routing/profiles/car.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ struct car {
3333

3434
constexpr node_idx_t get_key() const noexcept { return n_; }
3535

36-
void track(ways::routing const&, way_idx_t, node_idx_t) {}
37-
3836
std::ostream& print(std::ostream& out, ways const& w) const {
3937
return out << "(node=" << w.node_to_osm_[n_] << ", dir=" << to_str(dir_)
4038
<< ", way=" << w.way_osm_idx_[w.r_->node_ways_[n_][way_]]
@@ -53,7 +51,7 @@ struct car {
5351
constexpr node get_node() const noexcept { return {n_, way_, dir_}; }
5452
constexpr cost_t cost() const noexcept { return cost_; }
5553

56-
void track(ways::routing const&, way_idx_t, node_idx_t) {}
54+
void track(label const&, ways::routing const&, way_idx_t, node_idx_t) {}
5755

5856
node_idx_t n_;
5957
way_pos_t way_;

include/osr/routing/profiles/car_parking.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct car_parking {
9393

9494
constexpr cost_t cost() const noexcept { return cost_; }
9595

96-
void track(ways::routing const&, way_idx_t, node_idx_t) {}
96+
void track(label const&, ways::routing const&, way_idx_t, node_idx_t) {}
9797

9898
node_idx_t n_;
9999
cost_t cost_;

include/osr/routing/profiles/foot.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@ struct foot {
4141
constexpr node get_node() const noexcept { return {n_, lvl_}; }
4242
constexpr cost_t cost() const noexcept { return cost_; }
4343

44-
void track(ways::routing const& r, way_idx_t const w, node_idx_t const n) {
45-
tracking_.track(r, w, n);
44+
void track(label const& l,
45+
ways::routing const& r,
46+
way_idx_t const w,
47+
node_idx_t const n) {
48+
tracking_.track(l.tracking_, r, w, n);
4649
}
4750

4851
node_idx_t n_;

include/osr/routing/route.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ std::vector<std::optional<path>> route(
5656
cost_t max,
5757
direction,
5858
double max_match_distance,
59-
bitvec<node_idx_t> const* blocked = nullptr);
59+
bitvec<node_idx_t> const* blocked = nullptr,
60+
std::function<bool(path const&)> const& = [](path const&) {
61+
return false;
62+
});
6063

6164
std::optional<path> route(ways const&,
6265
lookup const&,

include/osr/routing/tracking.h

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,22 @@ namespace osr {
77

88
struct elevator_tracking {
99
void write(path& p) const { p.uses_elevator_ = uses_elevator_; }
10-
void track(ways::routing const& r, way_idx_t, node_idx_t const n) {
11-
uses_elevator_ |= r.node_properties_[n].is_elevator();
10+
void track(elevator_tracking const& l,
11+
ways::routing const& r,
12+
way_idx_t,
13+
node_idx_t const n) {
14+
uses_elevator_ = l.uses_elevator_ || r.node_properties_[n].is_elevator();
1215
}
1316

1417
bool uses_elevator_{false};
1518
};
1619

1720
struct noop_tracking {
1821
void write(path&) const {}
19-
void track(ways::routing const&, way_idx_t, node_idx_t) {}
22+
void track(noop_tracking const&,
23+
ways::routing const&,
24+
way_idx_t,
25+
node_idx_t) {}
2026
};
2127

2228
} // namespace osr

src/route.cc

+62-46
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ template <typename Profile>
203203
std::optional<std::tuple<node_candidate const*,
204204
way_candidate const*,
205205
typename Profile::node,
206-
cost_t>>
206+
path>>
207207
best_candidate(ways const& w,
208208
dijkstra<Profile>& d,
209209
level_t const lvl,
@@ -213,7 +213,7 @@ best_candidate(ways const& w,
213213
auto const get_best = [&](way_candidate const& dest,
214214
node_candidate const* x) {
215215
auto best_node = typename Profile::node{};
216-
auto best_cost = std::numeric_limits<cost_t>::max();
216+
auto best_cost = path{.cost_ = std::numeric_limits<cost_t>::max()};
217217
Profile::resolve_all(*w.r_, x->node_, lvl, [&](auto&& node) {
218218
if (!Profile::is_dest_reachable(*w.r_, node, dest.way_,
219219
flip(opposite(dir), x->way_dir_),
@@ -227,26 +227,26 @@ best_candidate(ways const& w,
227227
}
228228

229229
auto const total_cost = target_cost + x->cost_;
230-
if (total_cost < max && total_cost < best_cost) {
230+
if (total_cost < max && total_cost < best_cost.cost_) {
231231
best_node = node;
232-
best_cost = static_cast<cost_t>(total_cost);
232+
best_cost.cost_ = static_cast<cost_t>(total_cost);
233233
}
234234
});
235235
return std::pair{best_node, best_cost};
236236
};
237237

238238
for (auto const& dest : m) {
239239
auto best_node = typename Profile::node{};
240-
auto best_cost = std::numeric_limits<cost_t>::max();
240+
auto best_cost = path{.cost_ = std::numeric_limits<cost_t>::max()};
241241
auto best = static_cast<node_candidate const*>(nullptr);
242242

243243
for (auto const x : {&dest.left_, &dest.right_}) {
244244
if (x->valid() && x->cost_ < max) {
245245
auto const [x_node, x_cost] = get_best(dest, x);
246-
if (x_cost < max && x_cost < best_cost) {
246+
if (x_cost.cost_ < max && x_cost.cost_ < best_cost.cost_) {
247247
best = x;
248248
best_node = x_node;
249-
best_cost = static_cast<cost_t>(x_cost);
249+
best_cost = x_cost;
250250
}
251251
}
252252
}
@@ -282,10 +282,9 @@ std::optional<path> route(ways const& w,
282282
for (auto const& start : from_match) {
283283
for (auto const* nc : {&start.left_, &start.right_}) {
284284
if (nc->valid() && nc->cost_ < max) {
285-
Profile::resolve_start_node(*w.r_, start.way_, nc->node_, from.lvl_,
286-
dir, [&](auto const node) {
287-
d.add_start({node, nc->cost_});
288-
});
285+
Profile::resolve_start_node(
286+
*w.r_, start.way_, nc->node_, from.lvl_, dir,
287+
[&](auto const node) { d.add_start({node, nc->cost_}); });
289288
}
290289
}
291290

@@ -297,24 +296,27 @@ std::optional<path> route(ways const& w,
297296

298297
auto const c = best_candidate(w, d, to.lvl_, to_match, max, dir);
299298
if (c.has_value()) {
300-
auto const [nc, wc, node, cost] = *c;
301-
return reconstruct<Profile>(w, blocked, d, start, *nc, node, cost, dir);
299+
auto const [nc, wc, node, p] = *c;
300+
return reconstruct<Profile>(w, blocked, d, start, *nc, node, p.cost_,
301+
dir);
302302
}
303303
}
304304

305305
return std::nullopt;
306306
}
307307

308308
template <typename Profile>
309-
std::vector<std::optional<path>> route(ways const& w,
310-
lookup const& l,
311-
dijkstra<Profile>& d,
312-
location const& from,
313-
std::vector<location> const& to,
314-
cost_t const max,
315-
direction const dir,
316-
double const max_match_distance,
317-
bitvec<node_idx_t> const* blocked) {
309+
std::vector<std::optional<path>> route(
310+
ways const& w,
311+
lookup const& l,
312+
dijkstra<Profile>& d,
313+
location const& from,
314+
std::vector<location> const& to,
315+
cost_t const max,
316+
direction const dir,
317+
double const max_match_distance,
318+
bitvec<node_idx_t> const* blocked,
319+
std::function<bool(path const&)> const& do_reconstruct) {
318320
auto const from_match =
319321
l.match<Profile>(from, false, dir, max_match_distance, blocked);
320322
auto const to_match = utl::to_vec(to, [&](auto&& x) {
@@ -332,10 +334,9 @@ std::vector<std::optional<path>> route(ways const& w,
332334
for (auto const& start : from_match) {
333335
for (auto const* nc : {&start.left_, &start.right_}) {
334336
if (nc->valid() && nc->cost_ < max) {
335-
Profile::resolve_start_node(*w.r_, start.way_, nc->node_, from.lvl_,
336-
dir, [&](auto const node) {
337-
d.add_start({node, nc->cost_});
338-
});
337+
Profile::resolve_start_node(
338+
*w.r_, start.way_, nc->node_, from.lvl_, dir,
339+
[&](auto const node) { d.add_start({node, nc->cost_}); });
339340
}
340341
}
341342

@@ -348,7 +349,14 @@ std::vector<std::optional<path>> route(ways const& w,
348349
} else {
349350
auto const c = best_candidate(w, d, t.lvl_, m, max, dir);
350351
if (c.has_value()) {
351-
r = std::make_optional(path{.cost_ = std::get<3>(*c)});
352+
auto [nc, wc, n, p] = *c;
353+
d.cost_.at(n.get_key()).write(n, p);
354+
if (do_reconstruct(p)) {
355+
p = reconstruct<Profile>(w, blocked, d, start, *nc, n, p.cost_,
356+
dir);
357+
p.uses_elevator_ = true;
358+
}
359+
r = std::make_optional(p);
352360
++found;
353361
}
354362
}
@@ -371,34 +379,36 @@ dijkstra<Profile>& get_dijkstra() {
371379
return *s.get();
372380
}
373381

374-
std::vector<std::optional<path>> route(ways const& w,
375-
lookup const& l,
376-
search_profile const profile,
377-
location const& from,
378-
std::vector<location> const& to,
379-
cost_t const max,
380-
direction const dir,
381-
double const max_match_distance,
382-
bitvec<node_idx_t> const* blocked) {
382+
std::vector<std::optional<path>> route(
383+
ways const& w,
384+
lookup const& l,
385+
search_profile const profile,
386+
location const& from,
387+
std::vector<location> const& to,
388+
cost_t const max,
389+
direction const dir,
390+
double const max_match_distance,
391+
bitvec<node_idx_t> const* blocked,
392+
std::function<bool(path const&)> const& do_reconstruct) {
383393
switch (profile) {
384394
case search_profile::kFoot:
385-
return route(w, l, get_dijkstra<foot<false>>(), from, to, max, dir,
386-
max_match_distance, blocked);
395+
return route(w, l, get_dijkstra<foot<false, elevator_tracking>>(), from,
396+
to, max, dir, max_match_distance, blocked, do_reconstruct);
387397
case search_profile::kWheelchair:
388-
return route(w, l, get_dijkstra<foot<true>>(), from, to, max, dir,
389-
max_match_distance, blocked);
398+
return route(w, l, get_dijkstra<foot<true, elevator_tracking>>(), from,
399+
to, max, dir, max_match_distance, blocked, do_reconstruct);
390400
case search_profile::kBike:
391401
return route(w, l, get_dijkstra<bike>(), from, to, max, dir,
392-
max_match_distance, blocked);
402+
max_match_distance, blocked, do_reconstruct);
393403
case search_profile::kCar:
394404
return route(w, l, get_dijkstra<car>(), from, to, max, dir,
395-
max_match_distance, blocked);
405+
max_match_distance, blocked, do_reconstruct);
396406
case search_profile::kCarParking:
397407
return route(w, l, get_dijkstra<car_parking<false>>(), from, to, max, dir,
398-
max_match_distance, blocked);
408+
max_match_distance, blocked, do_reconstruct);
399409
case search_profile::kCarParkingWheelchair:
400410
return route(w, l, get_dijkstra<car_parking<true>>(), from, to, max, dir,
401-
max_match_distance, blocked);
411+
max_match_distance, blocked, do_reconstruct);
402412
}
403413
throw utl::fail("not implemented");
404414
}
@@ -414,8 +424,8 @@ std::optional<path> route(ways const& w,
414424
bitvec<node_idx_t> const* blocked) {
415425
switch (profile) {
416426
case search_profile::kFoot:
417-
return route(w, l, get_dijkstra<foot<false>>(), from, to, max, dir,
418-
max_match_distance, blocked);
427+
return route(w, l, get_dijkstra<foot<false, elevator_tracking>>(), from,
428+
to, max, dir, max_match_distance, blocked);
419429
case search_profile::kWheelchair:
420430
return route(w, l, get_dijkstra<foot<true, elevator_tracking>>(), from,
421431
to, max, dir, max_match_distance, blocked);
@@ -435,4 +445,10 @@ std::optional<path> route(ways const& w,
435445
throw utl::fail("not implemented");
436446
}
437447

448+
template dijkstra<foot<true, osr::noop_tracking>>&
449+
get_dijkstra<foot<true, osr::noop_tracking>>();
450+
451+
template dijkstra<foot<false, osr::noop_tracking>>&
452+
get_dijkstra<foot<false, osr::noop_tracking>>();
453+
438454
} // namespace osr

0 commit comments

Comments
 (0)