@@ -30,7 +30,7 @@ namespace osr {
3030
3131constexpr auto const kMaxMatchingDistanceSquaredRatio = 9.0 ;
3232
33- #define trace (...)
33+ #define trace (...) fmt::println(__VA_ARGS__)
3434
3535struct connecting_way {
3636 constexpr bool valid () const { return way_ != way_idx_t::invalid (); }
@@ -436,54 +436,44 @@ best_candidate(ways const& w,
436436 return std::pair{best_node, best_cost};
437437 };
438438
439- for (auto const accept_bad_max_matching_dist : {false , true }) {
440- for (auto const [j, dest] : utl::enumerate (m)) {
441- if (w.r_ ->way_component_ [start.way_ ] != w.r_ ->way_component_ [dest.way_ ]) {
442- trace (" reject {}: component mismatch {} vs {}" ,
443- w.way_osm_idx_ [dest.way_ ], w.r_ ->way_component_ [start.way_ ],
444- w.r_ ->way_component_ [dest.way_ ]);
445- continue ;
446- }
447- if (!should_continue && component_seen (w, m, j, 10 )) {
448- trace (" reject {}: should_continue={}, component_seen={}" ,
449- w.way_osm_idx_ [dest.way_ ], should_continue,
450- component_seen (w, m, j, 10 ));
451- continue ;
452- }
453- if (accept_bad_max_matching_dist &&
454- std::pow (dest.dist_to_way_ , 2 ) >
455- limit_squared_max_matching_distance) {
456- trace (" reject {}: limit squared matching distance: {} > {} " ,
457- w.way_osm_idx_ [dest.way_ ], dest.dist_to_way_ ,
458- std::sqrt (limit_squared_max_matching_distance));
459- break ;
460- } else if (std::pow (dest.dist_to_way_ , 2 ) >
461- limit_squared_max_matching_distance) {
462- trace (" WOULD reject {}: limit squared matching distance: {} > {} " ,
463- w.way_osm_idx_ [dest.way_ ], dest.dist_to_way_ ,
464- std::sqrt (limit_squared_max_matching_distance));
465- }
466- auto best_node = Profile::node::invalid ();
467- auto best_cost = path{.cost_ = std::numeric_limits<cost_t >::max ()};
468- auto best = static_cast <node_candidate const *>(nullptr );
469-
470- for (auto const x : {&dest.left_ , &dest.right_ }) {
471- if (x->valid ()) {
472- auto const [x_node, x_cost] = get_best (dest, x);
473- if (x_cost.cost_ < best_cost.cost_ ) {
474- best = x;
475- best_node = x_node;
476- best_cost = x_cost;
477- }
439+ for (auto const [j, dest] : utl::enumerate (m)) {
440+ if (w.r_ ->way_component_ [start.way_ ] != w.r_ ->way_component_ [dest.way_ ]) {
441+ trace (" reject {}: component mismatch {} vs {}" , w.way_osm_idx_ [dest.way_ ],
442+ w.r_ ->way_component_ [start.way_ ], w.r_ ->way_component_ [dest.way_ ]);
443+ continue ;
444+ }
445+ if (!should_continue && component_seen (w, m, j, 10 )) {
446+ trace (" reject {}: should_continue={}, component_seen={}" ,
447+ w.way_osm_idx_ [dest.way_ ], should_continue,
448+ component_seen (w, m, j, 10 ));
449+ continue ;
450+ }
451+ if (std::pow (dest.dist_to_way_ , 2 ) > limit_squared_max_matching_distance) {
452+ trace (" reject {}: limit squared matching distance: {} > {} " ,
453+ w.way_osm_idx_ [dest.way_ ], dest.dist_to_way_ ,
454+ std::sqrt (limit_squared_max_matching_distance));
455+ break ;
456+ }
457+ auto best_node = Profile::node::invalid ();
458+ auto best_cost = path{.cost_ = std::numeric_limits<cost_t >::max ()};
459+ auto best = static_cast <node_candidate const *>(nullptr );
460+
461+ for (auto const x : {&dest.left_ , &dest.right_ }) {
462+ if (x->valid ()) {
463+ auto const [x_node, x_cost] = get_best (dest, x);
464+ if (x_cost.cost_ < best_cost.cost_ ) {
465+ best = x;
466+ best_node = x_node;
467+ best_cost = x_cost;
478468 }
479469 }
470+ }
480471
481- if (best != nullptr ) {
482- trace (" MATCHED cost={} (max={})" , best_cost.cost_ , max);
483- return best_cost.cost_ < max ? std::optional{std::tuple{
484- best, &dest, best_node, best_cost}}
485- : std::nullopt ;
486- }
472+ if (best != nullptr ) {
473+ trace (" MATCHED cost={} (max={})" , best_cost.cost_ , max);
474+ return best_cost.cost_ < max
475+ ? std::optional{std::tuple{best, &dest, best_node, best_cost}}
476+ : std::nullopt ;
487477 }
488478 }
489479 trace (" NOTHING MATCHED" );
@@ -556,50 +546,45 @@ std::optional<path> route_bidirectional(ways const& w,
556546 if (b.pq1_ .empty ()) {
557547 continue ;
558548 }
559- for (auto const accept_bad_max_matching_dist : {false , true }) {
560- for (auto const [j, end] : utl::enumerate (to_match)) {
561- if (w.r_ ->way_component_ [start.way_ ] !=
562- w.r_ ->way_component_ [end.way_ ]) {
563- continue ;
564- }
565- if (b.max_reached_2_ && component_seen (w, to_match, j)) {
566- continue ;
567- }
568- if (accept_bad_max_matching_dist &&
569- std::pow (end.dist_to_way_ , 2 ) >
570- limit_squared_max_matching_distance) {
571- break ;
572- }
573- auto const end_way = end.way_ ;
574- for (auto const * nc : {&end.left_ , &end.right_ }) {
575- if (nc->valid () && nc->cost_ < max) {
576- Profile::resolve_start_node (
577- *w.r_ , end_way, nc->node_ , to.lvl_ , opposite (dir),
578- [&](auto const node) {
579- auto label = typename Profile::label{node, nc->cost_ };
580- label.track (label, *w.r_ , end_way, node.get_node (), false );
581- b.add_end (w, label, sharing);
582- });
583- }
584- }
585- if (b.pq2_ .empty ()) {
586- continue ;
549+ for (auto const [j, end] : utl::enumerate (to_match)) {
550+ if (w.r_ ->way_component_ [start.way_ ] != w.r_ ->way_component_ [end.way_ ]) {
551+ continue ;
552+ }
553+ if (b.max_reached_2_ && component_seen (w, to_match, j)) {
554+ continue ;
555+ }
556+ if (std::pow (end.dist_to_way_ , 2 ) > limit_squared_max_matching_distance) {
557+ break ;
558+ }
559+ auto const end_way = end.way_ ;
560+ for (auto const * nc : {&end.left_ , &end.right_ }) {
561+ if (nc->valid () && nc->cost_ < max) {
562+ Profile::resolve_start_node (
563+ *w.r_ , end_way, nc->node_ , to.lvl_ , opposite (dir),
564+ [&](auto const node) {
565+ auto label = typename Profile::label{node, nc->cost_ };
566+ label.track (label, *w.r_ , end_way, node.get_node (), false );
567+ b.add_end (w, label, sharing);
568+ });
587569 }
588- auto const should_continue =
589- b.run (w, *w.r_ , max, blocked, sharing, elevations, dir);
570+ }
571+ if (b.pq2_ .empty ()) {
572+ continue ;
573+ }
574+ auto const should_continue =
575+ b.run (w, *w.r_ , max, blocked, sharing, elevations, dir);
590576
591- if (b.meet_point_1_ .get_node () == node_idx_t::invalid ()) {
592- if (should_continue) {
593- continue ;
594- }
595- return std::nullopt ;
577+ if (b.meet_point_1_ .get_node () == node_idx_t::invalid ()) {
578+ if (should_continue) {
579+ continue ;
596580 }
581+ return std::nullopt ;
582+ }
597583
598- auto const cost = b.get_cost_to_mp (b.meet_point_1_ , b.meet_point_2_ );
584+ auto const cost = b.get_cost_to_mp (b.meet_point_1_ , b.meet_point_2_ );
599585
600- return reconstruct_bi (w, l, blocked, sharing, elevations, b, from, to,
601- start, end, cost, dir);
602- }
586+ return reconstruct_bi (w, l, blocked, sharing, elevations, b, from, to,
587+ start, end, cost, dir);
603588 }
604589 b.pq1_ .clear ();
605590 b.pq2_ .clear ();
@@ -626,45 +611,53 @@ std::optional<path> route_dijkstra(ways const& w,
626611 return *direct;
627612 }
628613
629- auto const limit_squared_max_matching_distance =
630- std::pow (geo::distance (from.pos_ , to.pos_ ), 2 ) /
631- kMaxMatchingDistanceSquaredRatio ;
614+ auto const distance_lng_degrees = geo::approx_distance_lng_degrees (from.pos_ );
632615
633616 d.reset (max);
634617 auto should_continue = true ;
635- for (auto const [i, start] : utl::enumerate (from_match)) {
636- if (!should_continue && component_seen (w, from_match, i)) {
637- continue ;
638- }
639- if (utl::none_of (to_match, [&](way_candidate const & end) {
640- return w.r_ ->way_component_ [start.way_ ] ==
641- w.r_ ->way_component_ [end.way_ ];
642- })) {
643- continue ;
644- }
645-
646- for (auto const * nc : {&start.left_ , &start.right_ }) {
647- if (nc->valid () && nc->cost_ < max) {
648- Profile::resolve_start_node (
649- *w.r_ , start.way_ , nc->node_ , from.lvl_ , dir,
650- [&](auto const node) { d.add_start (w, {node, nc->cost_ }); });
618+ for (auto const accept_bad_max_matching_dist : {false , true }) {
619+ auto const limit_squared_max_matching_distance =
620+ accept_bad_max_matching_dist
621+ ? std::numeric_limits<double >::max ()
622+ : geo::approx_squared_distance (from.pos_ , to.pos_ ,
623+ distance_lng_degrees) /
624+ kMaxMatchingDistanceSquaredRatio ;
625+
626+ for (auto const [i, start] : utl::enumerate (from_match)) {
627+ if (!should_continue && component_seen (w, from_match, i)) {
628+ continue ;
629+ }
630+ if (utl::none_of (to_match, [&](way_candidate const & end) {
631+ return w.r_ ->way_component_ [start.way_ ] ==
632+ w.r_ ->way_component_ [end.way_ ];
633+ })) {
634+ continue ;
651635 }
652- }
653636
654- if (d.pq_ .empty ()) {
655- continue ;
656- }
637+ for (auto const * nc : {&start.left_ , &start.right_ }) {
638+ if (nc->valid () && nc->cost_ < max) {
639+ Profile::resolve_start_node (
640+ *w.r_ , start.way_ , nc->node_ , from.lvl_ , dir,
641+ [&](auto const node) { d.add_start (w, {node, nc->cost_ }); });
642+ }
643+ }
657644
658- should_continue = d.run (w, *w.r_ , max, blocked, sharing, elevations, dir) &&
659- should_continue;
645+ if (d.pq_ .empty ()) {
646+ continue ;
647+ }
660648
661- auto const c =
662- best_candidate (w, d, to.lvl_ , to_match, max, dir, should_continue,
663- start, limit_squared_max_matching_distance);
664- if (c.has_value ()) {
665- auto const [nc, wc, node, p] = *c;
666- return reconstruct<Profile>(w, l, blocked, sharing, elevations, d, from,
667- to, start, *wc, *nc, node, p.cost_ , dir);
649+ should_continue =
650+ d.run (w, *w.r_ , max, blocked, sharing, elevations, dir) &&
651+ should_continue;
652+
653+ auto const c =
654+ best_candidate (w, d, to.lvl_ , to_match, max, dir, should_continue,
655+ start, limit_squared_max_matching_distance);
656+ if (c.has_value ()) {
657+ auto const [nc, wc, node, p] = *c;
658+ return reconstruct<Profile>(w, l, blocked, sharing, elevations, d, from,
659+ to, start, *wc, *nc, node, p.cost_ , dir);
660+ }
668661 }
669662 }
670663
@@ -697,56 +690,65 @@ std::vector<std::optional<path>> route(
697690
698691 d.reset (max);
699692 auto should_continue = true ;
700- for (auto const [i, start] : utl::enumerate (from_match)) {
701- if (!should_continue && component_seen (w, from_match, i)) {
702- continue ;
703- }
704- auto const start_way = start.way_ ;
705- for (auto const * nc : {&start.left_ , &start.right_ }) {
706- if (nc->valid () && nc->cost_ < max) {
707- Profile::resolve_start_node (
708- *w.r_ , start.way_ , nc->node_ , from.lvl_ , dir, [&](auto const node) {
709- auto label = typename Profile::label{node, nc->cost_ };
710- label.track (label, *w.r_ , start_way, node.get_node (), false );
711- d.add_start (w, label);
712- });
693+
694+ for (auto const accept_bad_max_matching_dist : {false , true }) {
695+ for (auto const [i, start] : utl::enumerate (from_match)) {
696+ if (!should_continue && component_seen (w, from_match, i)) {
697+ continue ;
698+ }
699+ auto const start_way = start.way_ ;
700+ for (auto const * nc : {&start.left_ , &start.right_ }) {
701+ if (nc->valid () && nc->cost_ < max) {
702+ Profile::resolve_start_node (
703+ *w.r_ , start.way_ , nc->node_ , from.lvl_ , dir,
704+ [&](auto const node) {
705+ auto label = typename Profile::label{node, nc->cost_ };
706+ label.track (label, *w.r_ , start_way, node.get_node (), false );
707+ d.add_start (w, label);
708+ });
709+ }
713710 }
714- }
715711
716- should_continue = d.run (w, *w.r_ , max, blocked, sharing, elevations, dir) &&
717- should_continue;
712+ should_continue =
713+ d.run (w, *w.r_ , max, blocked, sharing, elevations, dir) &&
714+ should_continue;
718715
719- auto found = 0U ;
720- for (auto const [m, t, r] : utl::zip (to_match, to, result)) {
721- if (r.has_value ()) {
722- ++found;
723- } else if (auto const direct = try_direct (from, t); direct.has_value ()) {
724- r = direct;
725- } else {
726- auto const limit_squared_max_matching_distance =
727- geo::approx_squared_distance (from.pos_ , t.pos_ ,
728- distance_lng_degrees) /
729- kMaxMatchingDistanceSquaredRatio ;
730-
731- auto const c =
732- best_candidate (w, d, t.lvl_ , m, max, dir, should_continue, start,
733- limit_squared_max_matching_distance);
734- if (c.has_value ()) {
735- auto [nc, wc, n, p] = *c;
736- d.cost_ .at (n.get_key ()).write (n, p);
737- if (do_reconstruct (p)) {
738- p = reconstruct<Profile>(w, l, blocked, sharing, elevations, d,
739- from, t, start, *wc, *nc, n, p.cost_ , dir);
740- p.uses_elevator_ = true ;
741- }
742- r = std::make_optional (p);
716+ auto found = 0U ;
717+ for (auto const [m, t, r] : utl::zip (to_match, to, result)) {
718+ if (r.has_value ()) {
743719 ++found;
720+ } else if (auto const direct = try_direct (from, t);
721+ direct.has_value ()) {
722+ r = direct;
723+ } else {
724+ auto const limit_squared_max_matching_distance =
725+ accept_bad_max_matching_dist
726+ ? std::numeric_limits<double >::max ()
727+ : geo::approx_squared_distance (from.pos_ , t.pos_ ,
728+ distance_lng_degrees) /
729+ kMaxMatchingDistanceSquaredRatio ;
730+
731+ auto const c =
732+ best_candidate (w, d, t.lvl_ , m, max, dir, should_continue, start,
733+ limit_squared_max_matching_distance);
734+ if (c.has_value ()) {
735+ auto [nc, wc, n, p] = *c;
736+ d.cost_ .at (n.get_key ()).write (n, p);
737+ if (do_reconstruct (p)) {
738+ p = reconstruct<Profile>(w, l, blocked, sharing, elevations, d,
739+ from, t, start, *wc, *nc, n, p.cost_ ,
740+ dir);
741+ p.uses_elevator_ = true ;
742+ }
743+ r = std::make_optional (p);
744+ ++found;
745+ }
744746 }
745747 }
746- }
747748
748- if (found == result.size ()) {
749- return result;
749+ if (found == result.size ()) {
750+ return result;
751+ }
750752 }
751753 }
752754
0 commit comments