@@ -112,22 +112,10 @@ double add_path(ways const& w,
112
112
segment.way_ = way;
113
113
segment.dist_ = distance;
114
114
segment.cost_ = expected_cost;
115
-
116
- // when going backwards we have to swap the properties, since we will be
117
- // traversing the way in the opposite direction.
118
- if (dir == direction::kForward ) {
119
- segment.from_level_ = r.way_properties_ [way].from_level ();
120
- segment.to_level_ = r.way_properties_ [way].to_level ();
121
-
122
- segment.from_node_properties_ = from.geojson_properties (w);
123
- segment.to_node_properties_ = to.geojson_properties (w);
124
- } else {
125
- segment.from_level_ = r.way_properties_ [way].to_level ();
126
- segment.to_level_ = r.way_properties_ [way].from_level ();
127
-
128
- segment.from_node_properties_ = to.geojson_properties (w);
129
- segment.to_node_properties_ = from.geojson_properties (w);
130
- }
115
+ segment.from_level_ = r.way_properties_ [way].from_level ();
116
+ segment.to_level_ = r.way_properties_ [way].to_level ();
117
+ segment.from_ = r.way_nodes_ [way][from_idx];
118
+ segment.to_ = r.way_nodes_ [way][to_idx];
131
119
132
120
for (auto const [osm_idx, coord] :
133
121
infinite (reverse (utl::zip (w.way_osm_nodes_ [way], w.way_polylines_ [way]),
@@ -183,14 +171,16 @@ path reconstruct(ways const& w,
183
171
184
172
auto const & start_node =
185
173
n.get_node () == start.left_ .node_ ? start.left_ : start.right_ ;
186
- segments.push_back ({.polyline_ = start_node.path_ ,
187
- .from_level_ = start_node.lvl_ ,
188
- .to_level_ = start_node.lvl_ ,
189
- .way_ = way_idx_t::invalid (),
190
- .cost_ = kInfeasible ,
191
- .dist_ = 0 ,
192
- .from_node_properties_ = {},
193
- .to_node_properties_ = {}});
174
+ segments.push_back (
175
+ {.polyline_ = start_node.path_ ,
176
+ .from_level_ = start_node.lvl_ ,
177
+ .to_level_ = start_node.lvl_ ,
178
+ .from_ =
179
+ dir == direction::kBackward ? n.get_node () : node_idx_t::invalid (),
180
+ .to_ = dir == direction::kForward ? n.get_node () : node_idx_t::invalid (),
181
+ .way_ = way_idx_t::invalid (),
182
+ .cost_ = kInfeasible ,
183
+ .dist_ = 0 });
194
184
std::reverse (begin (segments), end (segments));
195
185
auto p = path{.cost_ = cost,
196
186
.dist_ = start_node.dist_to_node_ + dist + dest.dist_to_node_ ,
@@ -203,7 +193,7 @@ template <typename Profile>
203
193
std::optional<std::tuple<node_candidate const *,
204
194
way_candidate const *,
205
195
typename Profile::node,
206
- cost_t >>
196
+ path >>
207
197
best_candidate (ways const & w,
208
198
dijkstra<Profile>& d,
209
199
level_t const lvl,
@@ -213,7 +203,7 @@ best_candidate(ways const& w,
213
203
auto const get_best = [&](way_candidate const & dest,
214
204
node_candidate const * x) {
215
205
auto best_node = typename Profile::node{};
216
- auto best_cost = std::numeric_limits<cost_t >::max ();
206
+ auto best_cost = path{. cost_ = std::numeric_limits<cost_t >::max ()} ;
217
207
Profile::resolve_all (*w.r_ , x->node_ , lvl, [&](auto && node) {
218
208
if (!Profile::is_dest_reachable (*w.r_ , node, dest.way_ ,
219
209
flip (opposite (dir), x->way_dir_ ),
@@ -227,26 +217,26 @@ best_candidate(ways const& w,
227
217
}
228
218
229
219
auto const total_cost = target_cost + x->cost_ ;
230
- if (total_cost < max && total_cost < best_cost) {
220
+ if (total_cost < max && total_cost < best_cost. cost_ ) {
231
221
best_node = node;
232
- best_cost = static_cast <cost_t >(total_cost);
222
+ best_cost. cost_ = static_cast <cost_t >(total_cost);
233
223
}
234
224
});
235
225
return std::pair{best_node, best_cost};
236
226
};
237
227
238
228
for (auto const & dest : m) {
239
229
auto best_node = typename Profile::node{};
240
- auto best_cost = std::numeric_limits<cost_t >::max ();
230
+ auto best_cost = path{. cost_ = std::numeric_limits<cost_t >::max ()} ;
241
231
auto best = static_cast <node_candidate const *>(nullptr );
242
232
243
233
for (auto const x : {&dest.left_ , &dest.right_ }) {
244
234
if (x->valid () && x->cost_ < max) {
245
235
auto const [x_node, x_cost] = get_best (dest, x);
246
- if (x_cost < max && x_cost < best_cost) {
236
+ if (x_cost. cost_ < max && x_cost. cost_ < best_cost. cost_ ) {
247
237
best = x;
248
238
best_node = x_node;
249
- best_cost = static_cast < cost_t >( x_cost) ;
239
+ best_cost = x_cost;
250
240
}
251
241
}
252
242
}
@@ -282,10 +272,9 @@ std::optional<path> route(ways const& w,
282
272
for (auto const & start : from_match) {
283
273
for (auto const * nc : {&start.left_ , &start.right_ }) {
284
274
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
- });
275
+ Profile::resolve_start_node (
276
+ *w.r_ , start.way_ , nc->node_ , from.lvl_ , dir,
277
+ [&](auto const node) { d.add_start ({node, nc->cost_ }); });
289
278
}
290
279
}
291
280
@@ -297,24 +286,27 @@ std::optional<path> route(ways const& w,
297
286
298
287
auto const c = best_candidate (w, d, to.lvl_ , to_match, max, dir);
299
288
if (c.has_value ()) {
300
- auto const [nc, wc, node, cost] = *c;
301
- return reconstruct<Profile>(w, blocked, d, start, *nc, node, cost, dir);
289
+ auto const [nc, wc, node, p] = *c;
290
+ return reconstruct<Profile>(w, blocked, d, start, *nc, node, p.cost_ ,
291
+ dir);
302
292
}
303
293
}
304
294
305
295
return std::nullopt;
306
296
}
307
297
308
298
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) {
299
+ std::vector<std::optional<path>> route (
300
+ ways const & w,
301
+ lookup const & l,
302
+ dijkstra<Profile>& d,
303
+ location const & from,
304
+ std::vector<location> const & to,
305
+ cost_t const max,
306
+ direction const dir,
307
+ double const max_match_distance,
308
+ bitvec<node_idx_t > const * blocked,
309
+ std::function<bool (path const &)> const & do_reconstruct) {
318
310
auto const from_match =
319
311
l.match <Profile>(from, false , dir, max_match_distance, blocked);
320
312
auto const to_match = utl::to_vec (to, [&](auto && x) {
@@ -332,10 +324,12 @@ std::vector<std::optional<path>> route(ways const& w,
332
324
for (auto const & start : from_match) {
333
325
for (auto const * nc : {&start.left_ , &start.right_ }) {
334
326
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
- });
327
+ Profile::resolve_start_node (
328
+ *w.r_ , start.way_ , nc->node_ , from.lvl_ , dir, [&](auto const node) {
329
+ auto label = typename Profile::label{node, nc->cost_ };
330
+ label.track (label, *w.r_ , start.way_ , node.get_node ());
331
+ d.add_start (label);
332
+ });
339
333
}
340
334
}
341
335
@@ -348,7 +342,14 @@ std::vector<std::optional<path>> route(ways const& w,
348
342
} else {
349
343
auto const c = best_candidate (w, d, t.lvl_ , m, max, dir);
350
344
if (c.has_value ()) {
351
- r = std::make_optional (path{.cost_ = std::get<3 >(*c)});
345
+ auto [nc, wc, n, p] = *c;
346
+ d.cost_ .at (n.get_key ()).write (n, p);
347
+ if (do_reconstruct (p)) {
348
+ p = reconstruct<Profile>(w, blocked, d, start, *nc, n, p.cost_ ,
349
+ dir);
350
+ p.uses_elevator_ = true ;
351
+ }
352
+ r = std::make_optional (p);
352
353
++found;
353
354
}
354
355
}
@@ -371,34 +372,36 @@ dijkstra<Profile>& get_dijkstra() {
371
372
return *s.get ();
372
373
}
373
374
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) {
375
+ std::vector<std::optional<path>> route (
376
+ ways const & w,
377
+ lookup const & l,
378
+ search_profile const profile,
379
+ location const & from,
380
+ std::vector<location> const & to,
381
+ cost_t const max,
382
+ direction const dir,
383
+ double const max_match_distance,
384
+ bitvec<node_idx_t > const * blocked,
385
+ std::function<bool (path const &)> const & do_reconstruct) {
383
386
switch (profile) {
384
387
case search_profile::kFoot :
385
- return route (w, l, get_dijkstra<foot<false >>(), from, to, max, dir ,
386
- max_match_distance, blocked);
388
+ return route (w, l, get_dijkstra<foot<false , elevator_tracking >>(), from,
389
+ to, max, dir, max_match_distance, blocked, do_reconstruct );
387
390
case search_profile::kWheelchair :
388
- return route (w, l, get_dijkstra<foot<true >>(), from, to, max, dir ,
389
- max_match_distance, blocked);
391
+ return route (w, l, get_dijkstra<foot<true , elevator_tracking >>(), from,
392
+ to, max, dir, max_match_distance, blocked, do_reconstruct );
390
393
case search_profile::kBike :
391
394
return route (w, l, get_dijkstra<bike>(), from, to, max, dir,
392
- max_match_distance, blocked);
395
+ max_match_distance, blocked, do_reconstruct );
393
396
case search_profile::kCar :
394
397
return route (w, l, get_dijkstra<car>(), from, to, max, dir,
395
- max_match_distance, blocked);
398
+ max_match_distance, blocked, do_reconstruct );
396
399
case search_profile::kCarParking :
397
400
return route (w, l, get_dijkstra<car_parking<false >>(), from, to, max, dir,
398
- max_match_distance, blocked);
401
+ max_match_distance, blocked, do_reconstruct );
399
402
case search_profile::kCarParkingWheelchair :
400
403
return route (w, l, get_dijkstra<car_parking<true >>(), from, to, max, dir,
401
- max_match_distance, blocked);
404
+ max_match_distance, blocked, do_reconstruct );
402
405
}
403
406
throw utl::fail (" not implemented" );
404
407
}
@@ -414,8 +417,8 @@ std::optional<path> route(ways const& w,
414
417
bitvec<node_idx_t > const * blocked) {
415
418
switch (profile) {
416
419
case search_profile::kFoot :
417
- return route (w, l, get_dijkstra<foot<false >>(), from, to, max, dir ,
418
- max_match_distance, blocked);
420
+ return route (w, l, get_dijkstra<foot<false , elevator_tracking >>(), from,
421
+ to, max, dir, max_match_distance, blocked);
419
422
case search_profile::kWheelchair :
420
423
return route (w, l, get_dijkstra<foot<true , elevator_tracking>>(), from,
421
424
to, max, dir, max_match_distance, blocked);
@@ -435,4 +438,10 @@ std::optional<path> route(ways const& w,
435
438
throw utl::fail (" not implemented" );
436
439
}
437
440
441
+ template dijkstra<foot<true , osr::noop_tracking>>&
442
+ get_dijkstra<foot<true , osr::noop_tracking>>();
443
+
444
+ template dijkstra<foot<false , osr::noop_tracking>>&
445
+ get_dijkstra<foot<false , osr::noop_tracking>>();
446
+
438
447
} // namespace osr
0 commit comments