get_ring.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Use, modification and distribution is subject to the Boost Software License,
  4. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
  7. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
  8. #include <boost/range.hpp>
  9. #include <boost/geometry/core/assert.hpp>
  10. #include <boost/geometry/core/exterior_ring.hpp>
  11. #include <boost/geometry/core/interior_rings.hpp>
  12. #include <boost/geometry/core/ring_type.hpp>
  13. #include <boost/geometry/core/tags.hpp>
  14. #include <boost/geometry/algorithms/detail/ring_identifier.hpp>
  15. #include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
  16. #include <boost/geometry/algorithms/num_points.hpp>
  17. #include <boost/geometry/geometries/concepts/check.hpp>
  18. #include <boost/geometry/util/range.hpp>
  19. namespace boost { namespace geometry
  20. {
  21. #ifndef DOXYGEN_NO_DETAIL
  22. namespace detail { namespace overlay
  23. {
  24. template<typename Tag>
  25. struct get_ring
  26. {};
  27. // A range of rings (multi-ring but that does not exist)
  28. // gets the "void" tag and is dispatched here.
  29. template<>
  30. struct get_ring<void>
  31. {
  32. template<typename Range>
  33. static inline typename boost::range_value<Range>::type const&
  34. apply(ring_identifier const& id, Range const& container)
  35. {
  36. return range::at(container, id.multi_index);
  37. }
  38. };
  39. template<>
  40. struct get_ring<ring_tag>
  41. {
  42. template<typename Ring>
  43. static inline Ring const& apply(ring_identifier const& , Ring const& ring)
  44. {
  45. return ring;
  46. }
  47. };
  48. template<>
  49. struct get_ring<box_tag>
  50. {
  51. template<typename Box>
  52. static inline Box const& apply(ring_identifier const& ,
  53. Box const& box)
  54. {
  55. return box;
  56. }
  57. };
  58. template<>
  59. struct get_ring<polygon_tag>
  60. {
  61. template<typename Polygon>
  62. static inline typename ring_return_type<Polygon const>::type const apply(
  63. ring_identifier const& id,
  64. Polygon const& polygon)
  65. {
  66. BOOST_GEOMETRY_ASSERT
  67. (
  68. id.ring_index >= -1
  69. && id.ring_index < int(boost::size(interior_rings(polygon)))
  70. );
  71. return id.ring_index < 0
  72. ? exterior_ring(polygon)
  73. : range::at(interior_rings(polygon), id.ring_index);
  74. }
  75. };
  76. template<>
  77. struct get_ring<multi_polygon_tag>
  78. {
  79. template<typename MultiPolygon>
  80. static inline typename ring_type<MultiPolygon>::type const& apply(
  81. ring_identifier const& id,
  82. MultiPolygon const& multi_polygon)
  83. {
  84. BOOST_GEOMETRY_ASSERT
  85. (
  86. id.multi_index >= 0
  87. && id.multi_index < int(boost::size(multi_polygon))
  88. );
  89. return get_ring<polygon_tag>::apply(id,
  90. range::at(multi_polygon, id.multi_index));
  91. }
  92. };
  93. template <typename Geometry>
  94. inline std::size_t segment_count_on_ring(Geometry const& geometry,
  95. segment_identifier const& seg_id)
  96. {
  97. typedef typename geometry::tag<Geometry>::type tag;
  98. ring_identifier const rid(0, seg_id.multi_index, seg_id.ring_index);
  99. // A closed polygon, a triangle of 4 points, including starting point,
  100. // contains 3 segments. So handle as if closed and subtract one.
  101. return geometry::num_points(detail::overlay::get_ring<tag>::apply(rid, geometry), true) - 1;
  102. }
  103. }} // namespace detail::overlay
  104. #endif // DOXYGEN_NO_DETAIL
  105. }} // namespace boost::geometry
  106. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP