@@ -103,10 +103,12 @@ namespace osmium {
103103 */
104104 class BasicAssembler {
105105
106+ static constexpr const std::size_t max_split_locations = 100ULL ;
107+
106108 struct slocation {
107109
108110 enum {
109- invalid_item = 1u << 30u
111+ invalid_item = 1U << 30U
110112 };
111113
112114 uint32_t item : 31 ;
@@ -271,7 +273,7 @@ namespace osmium {
271273
272274 using rings_stack = std::vector<rings_stack_element>;
273275
274- void remove_duplicates (rings_stack& outer_rings) {
276+ static void remove_duplicates (rings_stack& outer_rings) {
275277 while (true ) {
276278 const auto it = std::adjacent_find (outer_rings.begin (), outer_rings.end ());
277279 if (it == outer_rings.end ()) {
@@ -352,7 +354,8 @@ namespace osmium {
352354 std::cerr << " Segment is below (nesting=" << nesting << " )\n " ;
353355 }
354356 if (segment->ring ()->is_outer ()) {
355- const double y = ay + (by - ay) * (lx - ax) / double (bx - ax);
357+ const double y = static_cast <double >(ay) +
358+ static_cast <double >((by - ay) * (lx - ax)) / static_cast <double >(bx - ax);
356359 if (debug ()) {
357360 std::cerr << " Segment belongs to outer ring (y=" << y << " ring=" << *segment->ring () << " )\n " ;
358361 }
@@ -502,7 +505,12 @@ namespace osmium {
502505 void create_locations_list () {
503506 m_locations.reserve (m_segment_list.size () * 2 );
504507
505- for (uint32_t n = 0 ; n < m_segment_list.size (); ++n) {
508+ // static_cast is okay here: The 32bit limit is way past
509+ // anything that makes sense here and even if there are
510+ // 2^32 segments here, it would simply not go through
511+ // all of them not building the multipolygon correctly.
512+ assert (m_segment_list.size () < std::numeric_limits<uint32_t >::max ());
513+ for (uint32_t n = 0 ; n < static_cast <uint32_t >(m_segment_list.size ()); ++n) {
506514 m_locations.emplace_back (n, false );
507515 m_locations.emplace_back (n, true );
508516 }
@@ -1079,6 +1087,15 @@ namespace osmium {
10791087 timer_simple_case.start ();
10801088 create_rings_simple_case ();
10811089 timer_simple_case.stop ();
1090+ } else if (m_split_locations.size () > max_split_locations) {
1091+ if (debug ()) {
1092+ std::cerr << " Ignoring polygon with "
1093+ << m_split_locations.size ()
1094+ << " split locations (>"
1095+ << max_split_locations
1096+ << " )\n " ;
1097+ }
1098+ return false ;
10821099 } else {
10831100 if (debug ()) {
10841101 std::cerr << " Found split locations -> using complex algorithm\n " ;
0 commit comments