1 // Boost.Geometry 2 3 // Copyright (c) 2018 Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle 6 7 // Use, modification and distribution is subject to the Boost Software License, 8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_HPP 12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_HPP 13 14 #include <boost/geometry/core/cs.hpp> 15 #include <boost/geometry/core/tags.hpp> 16 17 #include <boost/geometry/iterators/segment_iterator.hpp> 18 19 #include <boost/geometry/algorithms/detail/envelope/range.hpp> 20 #include <boost/geometry/algorithms/detail/envelope/linear.hpp> 21 22 #include <boost/geometry/algorithms/dispatch/envelope.hpp> 23 24 namespace boost { namespace geometry 25 { 26 27 #ifndef DOXYGEN_NO_DETAIL 28 namespace detail { namespace envelope 29 { 30 31 template <typename EnvelopePolicy> 32 struct envelope_polygon 33 { 34 template <typename Polygon, typename Box, typename Strategy> applyboost::geometry::detail::envelope::envelope_polygon35 static inline void apply(Polygon const& polygon, Box& mbr, Strategy const& strategy) 36 { 37 typename ring_return_type<Polygon const>::type ext_ring 38 = exterior_ring(polygon); 39 40 if (geometry::is_empty(ext_ring)) 41 { 42 // if the exterior ring is empty, consider the interior rings 43 envelope_multi_range 44 < 45 EnvelopePolicy 46 >::apply(interior_rings(polygon), mbr, strategy); 47 } 48 else 49 { 50 // otherwise, consider only the exterior ring 51 EnvelopePolicy::apply(ext_ring, mbr, strategy); 52 } 53 } 54 }; 55 56 57 }} // namespace detail::envelope 58 #endif // DOXYGEN_NO_DETAIL 59 60 #ifndef DOXYGEN_NO_DISPATCH 61 namespace dispatch 62 { 63 64 65 template <typename Ring, typename CS_Tag> 66 struct envelope<Ring, ring_tag, CS_Tag> 67 : detail::envelope::envelope_range 68 {}; 69 70 template <typename Ring> 71 struct envelope<Ring, ring_tag, spherical_equatorial_tag> 72 : detail::envelope::envelope_linestring_or_ring_on_spheroid 73 {}; 74 75 template <typename Ring> 76 struct envelope<Ring, ring_tag, geographic_tag> 77 : detail::envelope::envelope_linestring_or_ring_on_spheroid 78 {}; 79 80 81 template <typename Polygon, typename CS_Tag> 82 struct envelope<Polygon, polygon_tag, CS_Tag> 83 : detail::envelope::envelope_polygon 84 < 85 detail::envelope::envelope_range 86 > 87 {}; 88 89 template <typename Polygon> 90 struct envelope<Polygon, polygon_tag, spherical_equatorial_tag> 91 : detail::envelope::envelope_polygon 92 < 93 detail::envelope::envelope_linestring_or_ring_on_spheroid 94 > 95 {}; 96 97 template <typename Polygon> 98 struct envelope<Polygon, polygon_tag, geographic_tag> 99 : detail::envelope::envelope_polygon 100 < 101 detail::envelope::envelope_linestring_or_ring_on_spheroid 102 > 103 {}; 104 105 106 template <typename MultiPolygon, typename CS_Tag> 107 struct envelope<MultiPolygon, multi_polygon_tag, CS_Tag> 108 : detail::envelope::envelope_multi_range 109 < 110 detail::envelope::envelope_polygon 111 < 112 detail::envelope::envelope_range 113 > 114 > 115 {}; 116 117 template <typename MultiPolygon> 118 struct envelope<MultiPolygon, multi_polygon_tag, spherical_equatorial_tag> 119 : detail::envelope::envelope_multi_range 120 < 121 detail::envelope::envelope_polygon 122 < 123 detail::envelope::envelope_linestring_or_ring_on_spheroid 124 > 125 > 126 {}; 127 128 template <typename MultiPolygon> 129 struct envelope<MultiPolygon, multi_polygon_tag, geographic_tag> 130 : detail::envelope::envelope_multi_range 131 < 132 detail::envelope::envelope_polygon 133 < 134 detail::envelope::envelope_linestring_or_ring_on_spheroid 135 > 136 > 137 {}; 138 139 140 } // namespace dispatch 141 #endif // DOXYGEN_NO_DISPATCH 142 143 144 }} // namespace boost::geometry 145 146 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_HPP 147