@@ -203,7 +203,7 @@ template <typename Profile>
203
203
std::optional<std::tuple<node_candidate const *,
204
204
way_candidate const *,
205
205
typename Profile::node,
206
- cost_t >>
206
+ path >>
207
207
best_candidate (ways const & w,
208
208
dijkstra<Profile>& d,
209
209
level_t const lvl,
@@ -213,7 +213,7 @@ best_candidate(ways const& w,
213
213
auto const get_best = [&](way_candidate const & dest,
214
214
node_candidate const * x) {
215
215
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 ()} ;
217
217
Profile::resolve_all (*w.r_ , x->node_ , lvl, [&](auto && node) {
218
218
if (!Profile::is_dest_reachable (*w.r_ , node, dest.way_ ,
219
219
flip (opposite (dir), x->way_dir_ ),
@@ -227,26 +227,26 @@ best_candidate(ways const& w,
227
227
}
228
228
229
229
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_ ) {
231
231
best_node = node;
232
- best_cost = static_cast <cost_t >(total_cost);
232
+ best_cost. cost_ = static_cast <cost_t >(total_cost);
233
233
}
234
234
});
235
235
return std::pair{best_node, best_cost};
236
236
};
237
237
238
238
for (auto const & dest : m) {
239
239
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 ()} ;
241
241
auto best = static_cast <node_candidate const *>(nullptr );
242
242
243
243
for (auto const x : {&dest.left_ , &dest.right_ }) {
244
244
if (x->valid () && x->cost_ < max) {
245
245
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_ ) {
247
247
best = x;
248
248
best_node = x_node;
249
- best_cost = static_cast < cost_t >( x_cost) ;
249
+ best_cost = x_cost;
250
250
}
251
251
}
252
252
}
@@ -282,10 +282,9 @@ std::optional<path> route(ways const& w,
282
282
for (auto const & start : from_match) {
283
283
for (auto const * nc : {&start.left_ , &start.right_ }) {
284
284
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_ }); });
289
288
}
290
289
}
291
290
@@ -297,24 +296,27 @@ std::optional<path> route(ways const& w,
297
296
298
297
auto const c = best_candidate (w, d, to.lvl_ , to_match, max, dir);
299
298
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);
302
302
}
303
303
}
304
304
305
305
return std::nullopt;
306
306
}
307
307
308
308
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) {
318
320
auto const from_match =
319
321
l.match <Profile>(from, false , dir, max_match_distance, blocked);
320
322
auto const to_match = utl::to_vec (to, [&](auto && x) {
@@ -332,10 +334,9 @@ std::vector<std::optional<path>> route(ways const& w,
332
334
for (auto const & start : from_match) {
333
335
for (auto const * nc : {&start.left_ , &start.right_ }) {
334
336
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_ }); });
339
340
}
340
341
}
341
342
@@ -348,7 +349,14 @@ std::vector<std::optional<path>> route(ways const& w,
348
349
} else {
349
350
auto const c = best_candidate (w, d, t.lvl_ , m, max, dir);
350
351
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);
352
360
++found;
353
361
}
354
362
}
@@ -371,34 +379,36 @@ dijkstra<Profile>& get_dijkstra() {
371
379
return *s.get ();
372
380
}
373
381
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) {
383
393
switch (profile) {
384
394
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 );
387
397
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 );
390
400
case search_profile::kBike :
391
401
return route (w, l, get_dijkstra<bike>(), from, to, max, dir,
392
- max_match_distance, blocked);
402
+ max_match_distance, blocked, do_reconstruct );
393
403
case search_profile::kCar :
394
404
return route (w, l, get_dijkstra<car>(), from, to, max, dir,
395
- max_match_distance, blocked);
405
+ max_match_distance, blocked, do_reconstruct );
396
406
case search_profile::kCarParking :
397
407
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 );
399
409
case search_profile::kCarParkingWheelchair :
400
410
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 );
402
412
}
403
413
throw utl::fail (" not implemented" );
404
414
}
@@ -414,8 +424,8 @@ std::optional<path> route(ways const& w,
414
424
bitvec<node_idx_t > const * blocked) {
415
425
switch (profile) {
416
426
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);
419
429
case search_profile::kWheelchair :
420
430
return route (w, l, get_dijkstra<foot<true , elevator_tracking>>(), from,
421
431
to, max, dir, max_match_distance, blocked);
@@ -435,4 +445,10 @@ std::optional<path> route(ways const& w,
435
445
throw utl::fail (" not implemented" );
436
446
}
437
447
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
+
438
454
} // namespace osr
0 commit comments