1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 5 // Use, modification and distribution is subject to the Boost Software License, 6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP 10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP 11 12 13 #include <boost/mpl/assert.hpp> 14 #include <boost/range.hpp> 15 #include <boost/range/algorithm/reverse.hpp> 16 17 #include <boost/geometry/core/tags.hpp> 18 #include <boost/geometry/core/exterior_ring.hpp> 19 #include <boost/geometry/core/interior_rings.hpp> 20 #include <boost/geometry/algorithms/detail/ring_identifier.hpp> 21 22 #include <boost/geometry/algorithms/convert.hpp> 23 24 25 namespace boost { namespace geometry 26 { 27 28 29 #ifndef DOXYGEN_NO_DETAIL 30 namespace detail { namespace overlay 31 { 32 33 34 template<typename Tag> 35 struct convert_ring 36 { 37 BOOST_MPL_ASSERT_MSG 38 ( 39 false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TAG 40 , (types<Tag>) 41 ); 42 }; 43 44 template<> 45 struct convert_ring<ring_tag> 46 { 47 template<typename Destination, typename Source> applyboost::geometry::detail::overlay::convert_ring48 static inline void apply(Destination& destination, Source const& source, 49 bool append, bool reverse) 50 { 51 if (! append) 52 { 53 geometry::convert(source, destination); 54 if (reverse) 55 { 56 boost::reverse(destination); 57 } 58 } 59 } 60 }; 61 62 63 template<> 64 struct convert_ring<polygon_tag> 65 { 66 template<typename Destination, typename Source> applyboost::geometry::detail::overlay::convert_ring67 static inline void apply(Destination& destination, Source const& source, 68 bool append, bool reverse) 69 { 70 if (! append) 71 { 72 geometry::convert(source, exterior_ring(destination)); 73 if (reverse) 74 { 75 boost::reverse(exterior_ring(destination)); 76 } 77 } 78 else 79 { 80 // Avoid adding interior rings which are invalid 81 // because of its number of points: 82 std::size_t const min_num_points 83 = core_detail::closure::minimum_ring_size 84 < 85 geometry::closure<Destination>::value 86 >::value; 87 88 if (geometry::num_points(source) >= min_num_points) 89 { 90 interior_rings(destination).resize( 91 interior_rings(destination).size() + 1); 92 geometry::convert(source, interior_rings(destination).back()); 93 if (reverse) 94 { 95 boost::reverse(interior_rings(destination).back()); 96 } 97 } 98 } 99 } 100 }; 101 102 103 }} // namespace detail::overlay 104 #endif // DOXYGEN_NO_DETAIL 105 106 107 }} // namespace boost::geometry 108 109 110 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP 111