range_by_section.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  7. // This file was modified by Oracle on 2013, 2014.
  8. // Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
  9. // Use, modification and distribution is subject to the Boost Software License,
  10. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  13. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
  14. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
  15. #include <boost/mpl/assert.hpp>
  16. #include <boost/range.hpp>
  17. #include <boost/geometry/core/access.hpp>
  18. #include <boost/geometry/core/assert.hpp>
  19. #include <boost/geometry/core/closure.hpp>
  20. #include <boost/geometry/core/exterior_ring.hpp>
  21. #include <boost/geometry/core/interior_rings.hpp>
  22. #include <boost/geometry/core/ring_type.hpp>
  23. #include <boost/geometry/core/tags.hpp>
  24. #include <boost/geometry/geometries/concepts/check.hpp>
  25. #include <boost/geometry/util/range.hpp>
  26. namespace boost { namespace geometry
  27. {
  28. #ifndef DOXYGEN_NO_DETAIL
  29. namespace detail { namespace section
  30. {
  31. template <typename Range, typename Section>
  32. struct full_section_range
  33. {
  34. static inline Range const& apply(Range const& range, Section const& )
  35. {
  36. return range;
  37. }
  38. };
  39. template <typename Polygon, typename Section>
  40. struct full_section_polygon
  41. {
  42. static inline typename ring_return_type<Polygon const>::type apply(Polygon const& polygon, Section const& section)
  43. {
  44. return section.ring_id.ring_index < 0
  45. ? geometry::exterior_ring(polygon)
  46. : range::at(geometry::interior_rings(polygon),
  47. static_cast<std::size_t>(section.ring_id.ring_index));
  48. }
  49. };
  50. template
  51. <
  52. typename MultiGeometry,
  53. typename Section,
  54. typename Policy
  55. >
  56. struct full_section_multi
  57. {
  58. static inline typename ring_return_type<MultiGeometry const>::type apply(
  59. MultiGeometry const& multi, Section const& section)
  60. {
  61. typedef typename boost::range_size<MultiGeometry>::type size_type;
  62. BOOST_GEOMETRY_ASSERT
  63. (
  64. section.ring_id.multi_index >= 0
  65. && size_type(section.ring_id.multi_index) < boost::size(multi)
  66. );
  67. return Policy::apply(range::at(multi, size_type(section.ring_id.multi_index)), section);
  68. }
  69. };
  70. }} // namespace detail::section
  71. #endif
  72. #ifndef DOXYGEN_NO_DISPATCH
  73. namespace dispatch
  74. {
  75. template
  76. <
  77. typename Tag,
  78. typename Geometry,
  79. typename Section
  80. >
  81. struct range_by_section
  82. {
  83. BOOST_MPL_ASSERT_MSG
  84. (
  85. false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
  86. , (types<Geometry>)
  87. );
  88. };
  89. template <typename LineString, typename Section>
  90. struct range_by_section<linestring_tag, LineString, Section>
  91. : detail::section::full_section_range<LineString, Section>
  92. {};
  93. template <typename Ring, typename Section>
  94. struct range_by_section<ring_tag, Ring, Section>
  95. : detail::section::full_section_range<Ring, Section>
  96. {};
  97. template <typename Polygon, typename Section>
  98. struct range_by_section<polygon_tag, Polygon, Section>
  99. : detail::section::full_section_polygon<Polygon, Section>
  100. {};
  101. template <typename MultiPolygon, typename Section>
  102. struct range_by_section<multi_polygon_tag, MultiPolygon, Section>
  103. : detail::section::full_section_multi
  104. <
  105. MultiPolygon,
  106. Section,
  107. detail::section::full_section_polygon
  108. <
  109. typename boost::range_value<MultiPolygon>::type,
  110. Section
  111. >
  112. >
  113. {};
  114. template <typename MultiLinestring, typename Section>
  115. struct range_by_section<multi_linestring_tag, MultiLinestring, Section>
  116. : detail::section::full_section_multi
  117. <
  118. MultiLinestring,
  119. Section,
  120. detail::section::full_section_range
  121. <
  122. typename boost::range_value<MultiLinestring>::type,
  123. Section
  124. >
  125. >
  126. {};
  127. } // namespace dispatch
  128. #endif
  129. /*!
  130. \brief Get full ring (exterior, one of interiors, one from multi)
  131. indicated by the specified section
  132. \ingroup sectionalize
  133. \tparam Geometry type
  134. \tparam Section type of section to get from
  135. \param geometry geometry to take section of
  136. \param section structure with section
  137. */
  138. template <typename Geometry, typename Section>
  139. inline typename ring_return_type<Geometry const>::type
  140. range_by_section(Geometry const& geometry, Section const& section)
  141. {
  142. concepts::check<Geometry const>();
  143. return dispatch::range_by_section
  144. <
  145. typename tag<Geometry>::type,
  146. Geometry,
  147. Section
  148. >::apply(geometry, section);
  149. }
  150. }} // namespace boost::geometry
  151. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP