55
66This file is part of Osmium (https://osmcode.org/libosmium).
77
8- Copyright 2013-2020 Jochen Topf <[email protected] > and others (see README). 8+ Copyright 2013-2021 Jochen Topf <[email protected] > and others (see README). 99
1010Boost Software License - Version 1.0 - August 17th, 2003
1111
@@ -51,6 +51,7 @@ DEALINGS IN THE SOFTWARE.
5151#include < cassert>
5252#include < cstdint>
5353#include < cstdlib>
54+ #include < exception>
5455#include < iostream>
5556#include < iterator>
5657#include < list>
@@ -384,7 +385,7 @@ namespace osmium {
384385 }
385386 assert (!outer_rings.empty ());
386387
387- std::sort (outer_rings.rbegin (), outer_rings.rend ());
388+ std::stable_sort (outer_rings.rbegin (), outer_rings.rend ());
388389 if (debug ()) {
389390 for (const auto & o : outer_rings) {
390391 std::cerr << " y=" << o.y () << " " << o.ring () << " \n " ;
@@ -552,7 +553,7 @@ namespace osmium {
552553 return ;
553554 }
554555
555- std::sort (rings.begin (), rings.end (), [](ProtoRing* a, ProtoRing* b) {
556+ std::stable_sort (rings.begin (), rings.end (), [](ProtoRing* a, ProtoRing* b) {
556557 return a->min_segment () < b->min_segment ();
557558 });
558559
@@ -618,7 +619,7 @@ namespace osmium {
618619 }
619620 }
620621
621- std::vector<location_to_ring_map> create_location_to_ring_map (open_ring_its_type& open_ring_its) {
622+ std::vector<location_to_ring_map> create_location_to_ring_map (open_ring_its_type& open_ring_its) const {
622623 std::vector<location_to_ring_map> xrings;
623624 xrings.reserve (open_ring_its.size () * 2 );
624625
@@ -630,7 +631,7 @@ namespace osmium {
630631 xrings.emplace_back ((*it)->get_node_ref_stop ().location (), it, false );
631632 }
632633
633- std::sort (xrings.begin (), xrings.end ());
634+ std::stable_sort (xrings.begin (), xrings.end ());
634635
635636 return xrings;
636637 }
@@ -719,9 +720,11 @@ namespace osmium {
719720
720721 };
721722
722- struct exceeded_max_depth {};
723+ struct exceeded_max_depth : public std ::exception {};
723724
724- 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 ) {
725+ using location_set = std::vector<osmium::Location>;
726+
727+ void find_candidates (std::vector<candidate>& candidates, location_set& loc_done, const std::vector<location_to_ring_map>& xrings, const candidate& cand, unsigned depth = 0 ) {
725728 if (depth > max_depth) {
726729 throw exceeded_max_depth{};
727730 }
@@ -781,13 +784,14 @@ namespace osmium {
781784 candidates.back () = c;
782785 }
783786 }
784- } else if (loc_done.count ( c.stop_location ) == 0 ) {
787+ } else if (std::find ( loc_done.cbegin (), loc_done. cend (), c.stop_location ) == loc_done. cend () ) {
785788 if (debug ()) {
786- std::cerr << " recurse... (depth=" << depth << " candidates.size=" << candidates.size () << " )\n " ;
789+ std::cerr << " recurse... (depth=" << depth << " candidates.size=" << candidates.size () << " loc_done.size= " << loc_done. size () << " )\n " ;
787790 }
788- loc_done.insert (c.stop_location );
791+ loc_done.push_back (c.stop_location );
789792 find_candidates (candidates, loc_done, xrings, c, depth + 1 );
790- loc_done.erase (c.stop_location );
793+ assert (!loc_done.empty () && loc_done.back () == c.stop_location );
794+ loc_done.pop_back ();
791795 if (debug ()) {
792796 std::cerr << " ...back\n " ;
793797 }
@@ -833,9 +837,9 @@ namespace osmium {
833837
834838 // Locations we have visited while finding candidates, used
835839 // to detect loops.
836- std::unordered_set<osmium::Location> loc_done;
840+ location_set loc_done;
837841
838- loc_done.insert (cand.stop_location );
842+ loc_done.push_back (cand.stop_location );
839843
840844 std::vector<candidate> candidates;
841845 try {
@@ -1106,17 +1110,16 @@ namespace osmium {
11061110 // whether there were any split locations or not. If there
11071111 // are no splits, we use the faster "simple algorithm", if
11081112 // there are, we use the slower "complex algorithm".
1109- osmium::Timer timer_simple_case;
1110- osmium::Timer timer_complex_case;
1113+ osmium::Timer timer;
11111114 if (m_split_locations.empty ()) {
11121115 if (debug ()) {
11131116 std::cerr << " No split locations -> using simple algorithm\n " ;
11141117 }
11151118 ++m_stats.area_simple_case ;
11161119
1117- timer_simple_case .start ();
1120+ timer .start ();
11181121 create_rings_simple_case ();
1119- timer_simple_case .stop ();
1122+ timer .stop ();
11201123 } else if (m_split_locations.size () > max_split_locations) {
11211124 if (m_config.debug_level > 0 ) {
11221125 std::cerr << " Ignoring polygon with "
@@ -1134,11 +1137,11 @@ namespace osmium {
11341137 }
11351138 ++m_stats.area_touching_rings_case ;
11361139
1137- timer_complex_case .start ();
1140+ timer .start ();
11381141 if (!create_rings_complex_case ()) {
11391142 return false ;
11401143 }
1141- timer_complex_case .stop ();
1144+ timer .stop ();
11421145 }
11431146
11441147 // If the assembler was so configured, now check whether the
@@ -1163,11 +1166,9 @@ namespace osmium {
11631166 ' ' << timer_split.elapsed_microseconds ();
11641167
11651168 if (m_split_locations.empty ()) {
1166- std::cout << ' ' << timer_simple_case.elapsed_microseconds () <<
1167- " 0" ;
1169+ std::cout << ' ' << timer.elapsed_microseconds () << " 0" ;
11681170 } else {
1169- std::cout << " 0" <<
1170- ' ' << timer_complex_case.elapsed_microseconds ();
1171+ std::cout << " 0" << ' ' << timer.elapsed_microseconds ();
11711172 }
11721173
11731174 std::cout <<
0 commit comments