@@ -713,7 +713,7 @@ namespace osmium {
713713
714714 };
715715
716- void find_candidates (std::vector<candidate>& candidates, std::unordered_set<osmium::Location>& loc_done, const std::vector<location_to_ring_map>& xrings, candidate& cand) {
716+ void find_candidates (std::vector<candidate>& candidates, std::unordered_set<osmium::Location>& loc_done, const std::vector<location_to_ring_map>& xrings, const candidate& cand, unsigned depth = 0 ) {
717717 if (debug ()) {
718718 std::cerr << " find_candidates sum=" << cand.sum << " start=" << cand.start_location << " stop=" << cand.stop_location << " \n " ;
719719 for (const auto & ring : cand.rings ) {
@@ -751,13 +751,30 @@ namespace osmium {
751751 if (debug ()) {
752752 std::cerr << " found candidate\n " ;
753753 }
754- candidates.push_back (c);
754+
755+ if (candidates.empty ()) {
756+ candidates.push_back (c);
757+ } else if (candidates.size () == 1 ) {
758+ // add new candidate to vector, keep sorted
759+ if (std::abs (c.sum ) < std::abs (candidates.front ().sum )) {
760+ candidates.insert (candidates.begin (), c);
761+ } else {
762+ candidates.push_back (c);
763+ }
764+ } else {
765+ // add new candidate if it has either smallest or largest area
766+ if (std::abs (c.sum ) < std::abs (candidates.front ().sum )) {
767+ candidates.front () = c;
768+ } else if (std::abs (c.sum ) > std::abs (candidates.back ().sum )) {
769+ candidates.back () = c;
770+ }
771+ }
755772 } else if (loc_done.count (c.stop_location ) == 0 ) {
756773 if (debug ()) {
757- std::cerr << " recurse...\n " ;
774+ std::cerr << " recurse... (depth= " << depth << " candidates.size= " << candidates. size () << " ) \n " ;
758775 }
759776 loc_done.insert (c.stop_location );
760- find_candidates (candidates, loc_done, xrings, c);
777+ find_candidates (candidates, loc_done, xrings, c, depth + 1 );
761778 loc_done.erase (c.stop_location );
762779 if (debug ()) {
763780 std::cerr << " ...back\n " ;
@@ -800,7 +817,7 @@ namespace osmium {
800817 ring.reset ();
801818 }
802819
803- candidate cand{*ring_min, false };
820+ const candidate cand{*ring_min, false };
804821
805822 // Locations we have visited while finding candidates, used
806823 // to detect loops.
@@ -838,26 +855,20 @@ namespace osmium {
838855 }
839856
840857 // Find the candidate with the smallest/largest area
841- const auto chosen_cand = ring_min_is_outer ?
842- std::min_element (candidates.cbegin (), candidates.cend (), [](const candidate& lhs, const candidate& rhs) {
843- return std::abs (lhs.sum ) < std::abs (rhs.sum );
844- }) :
845- std::max_element (candidates.cbegin (), candidates.cend (), [](const candidate& lhs, const candidate& rhs) {
846- return std::abs (lhs.sum ) < std::abs (rhs.sum );
847- });
858+ const auto chosen_cand = ring_min_is_outer ? candidates.front () : candidates.back ();
848859
849860 if (debug ()) {
850- std::cerr << " Decided on: sum=" << chosen_cand-> sum << " \n " ;
851- for (const auto & ring : chosen_cand-> rings ) {
861+ std::cerr << " Decided on: sum=" << chosen_cand. sum << " \n " ;
862+ for (const auto & ring : chosen_cand. rings ) {
852863 std::cerr << " " << ring.first .ring () << (ring.second ? " reverse" : " " ) << " \n " ;
853864 }
854865 }
855866
856867 // Join all (open) rings in the candidate to get one closed ring.
857- assert (chosen_cand-> rings .size () > 1 );
858- const auto & first_ring = chosen_cand-> rings .front ().first ;
868+ assert (chosen_cand. rings .size () > 1 );
869+ const auto & first_ring = chosen_cand. rings .front ().first ;
859870 const ProtoRing& remaining_ring = first_ring.ring ();
860- for (auto it = std::next (chosen_cand-> rings .begin ()); it != chosen_cand-> rings .end (); ++it) {
871+ for (auto it = std::next (chosen_cand. rings .begin ()); it != chosen_cand. rings .end (); ++it) {
861872 merge_two_rings (open_ring_its, first_ring, it->first );
862873 }
863874
@@ -1088,7 +1099,7 @@ namespace osmium {
10881099 create_rings_simple_case ();
10891100 timer_simple_case.stop ();
10901101 } else if (m_split_locations.size () > max_split_locations) {
1091- if (debug () ) {
1102+ if (m_config. debug_level > 0 ) {
10921103 std::cerr << " Ignoring polygon with "
10931104 << m_split_locations.size ()
10941105 << " split locations (>"
@@ -1097,8 +1108,10 @@ namespace osmium {
10971108 }
10981109 return false ;
10991110 } else {
1100- if (debug ()) {
1101- std::cerr << " Found split locations -> using complex algorithm\n " ;
1111+ if (m_config.debug_level > 0 ) {
1112+ std::cerr << " Found "
1113+ << m_split_locations.size ()
1114+ << " split locations -> using complex algorithm\n " ;
11021115 }
11031116 ++m_stats.area_touching_rings_case ;
11041117
0 commit comments