@@ -30,7 +30,7 @@ namespace osr {
30
30
31
31
constexpr auto const kMaxMatchingDistanceSquaredRatio = 9.0 ;
32
32
33
- #define trace (...)
33
+ #define trace (...)
34
34
35
35
struct connecting_way {
36
36
constexpr bool valid () const { return way_ != way_idx_t::invalid (); }
@@ -436,54 +436,44 @@ best_candidate(ways const& w,
436
436
return std::pair{best_node, best_cost};
437
437
};
438
438
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;
478
468
}
479
469
}
470
+ }
480
471
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 ;
487
477
}
488
478
}
489
479
trace (" NOTHING MATCHED" );
@@ -556,50 +546,45 @@ std::optional<path> route_bidirectional(ways const& w,
556
546
if (b.pq1_ .empty ()) {
557
547
continue ;
558
548
}
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
+ });
587
569
}
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);
590
576
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 ;
596
580
}
581
+ return std::nullopt ;
582
+ }
597
583
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_ );
599
585
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);
603
588
}
604
589
b.pq1_ .clear ();
605
590
b.pq2_ .clear ();
@@ -626,45 +611,53 @@ std::optional<path> route_dijkstra(ways const& w,
626
611
return *direct;
627
612
}
628
613
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_ );
632
615
633
616
d.reset (max);
634
617
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 ;
651
635
}
652
- }
653
636
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
+ }
657
644
658
- should_continue = d.run (w, *w.r_ , max, blocked, sharing, elevations, dir) &&
659
- should_continue;
645
+ if (d.pq_ .empty ()) {
646
+ continue ;
647
+ }
660
648
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
+ }
668
661
}
669
662
}
670
663
@@ -697,56 +690,65 @@ std::vector<std::optional<path>> route(
697
690
698
691
d.reset (max);
699
692
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
+ }
713
710
}
714
- }
715
711
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;
718
715
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 ()) {
743
719
++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
+ }
744
746
}
745
747
}
746
- }
747
748
748
- if (found == result.size ()) {
749
- return result;
749
+ if (found == result.size ()) {
750
+ return result;
751
+ }
750
752
}
751
753
}
752
754
0 commit comments