static inline void apply(Ring const& ring, SegmentIdentifier const& seg_id, signed_size_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { typedef typename closeable_view < Ring const, closure<Ring>::value >::type cview_type; typedef typename reversible_view < cview_type const, Reverse ? iterate_reverse : iterate_forward >::type rview_type; typedef typename boost::range_iterator<rview_type const>::type iterator; typedef geometry::ever_circling_iterator<iterator> ec_iterator; cview_type cview(ring); rview_type view(cview); // The problem: sometimes we want to from "3" to "2" // -> end = "3" -> end == begin // This is not convenient with iterators. // So we use the ever-circling iterator and determine when to step out signed_size_type const from_index = seg_id.segment_index + 1; // Sanity check BOOST_GEOMETRY_ASSERT(from_index < static_cast<signed_size_type>(boost::size(view))); ec_iterator it(boost::begin(view), boost::end(view), boost::begin(view) + from_index); // [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK // [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK // [1..1], travel the whole ring round signed_size_type const count = from_index <= to_index ? to_index - from_index + 1 : static_cast<signed_size_type>(boost::size(view)) - from_index + to_index + 1; for (signed_size_type i = 0; i < count; ++i, ++it) { detail::overlay::append_no_dups_or_spikes(current_output, *it, robust_policy); } }
static inline void apply(Range const& range, Sections& sections, ring_identifier ring_id) { typedef model::referring_segment<Point const> segment_type; cview_type cview(range); view_type view(cview); std::size_t const n = boost::size(view); if (n == 0) { // Zero points, no section return; } if (n == 1) { // Line with one point ==> no sections return; } int index = 0; int ndi = 0; // non duplicate index typedef typename boost::range_value<Sections>::type section_type; section_type section; sectionalize_part < view_type, Point, Sections, DimensionCount, MaxCount >::apply(sections, section, index, ndi, view, ring_id); // Add last section if applicable if (section.count > 0) { sections.push_back(section); } }
void test_sectionalize(std::string const caseid, Geometry const& geometry, std::size_t section_count) { typedef typename bg::point_type<Geometry>::type point; typedef bg::model::box<point> box; typedef bg::sections<box, DimensionCount> sections; sections s; bg::sectionalize<Reverse>(geometry, s); BOOST_CHECK_EQUAL(s.size(), section_count); typedef typename bg::closeable_view < typename bg::range_type<Geometry>::type const, bg::closure<Geometry>::value >::type cview_type; typedef typename bg::reversible_view < cview_type const, Reverse ? bg::iterate_reverse : bg::iterate_forward >::type view_type; typedef typename boost::range_iterator < view_type const >::type range_iterator; BOOST_FOREACH(typename sections::value_type const& sec, s) { cview_type cview(bg::range_by_section(geometry, sec)); view_type view(cview); range_iterator it1 = boost::begin(view) + sec.begin_index; range_iterator it2 = boost::begin(view) + sec.end_index; int count = 0; for (range_iterator it = it1; it != it2; ++it) { count++; } BOOST_CHECK_EQUAL(int(sec.count), count); }