union.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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_UNION_HPP
  7. #define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
  8. #include <boost/range/metafunctions.hpp>
  9. #include <boost/geometry/core/is_areal.hpp>
  10. #include <boost/geometry/core/point_order.hpp>
  11. #include <boost/geometry/core/reverse_dispatch.hpp>
  12. #include <boost/geometry/geometries/concepts/check.hpp>
  13. #include <boost/geometry/algorithms/not_implemented.hpp>
  14. #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
  15. namespace boost { namespace geometry
  16. {
  17. #ifndef DOXYGEN_NO_DISPATCH
  18. namespace dispatch
  19. {
  20. template
  21. <
  22. typename Geometry1, typename Geometry2, typename GeometryOut,
  23. typename TagIn1 = typename tag<Geometry1>::type,
  24. typename TagIn2 = typename tag<Geometry2>::type,
  25. typename TagOut = typename tag<GeometryOut>::type,
  26. bool Areal1 = geometry::is_areal<Geometry1>::value,
  27. bool Areal2 = geometry::is_areal<Geometry2>::value,
  28. bool ArealOut = geometry::is_areal<GeometryOut>::value,
  29. bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
  30. bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
  31. bool ReverseOut = detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
  32. bool Reverse = geometry::reverse_dispatch<Geometry1, Geometry2>::type::value
  33. >
  34. struct union_insert: not_implemented<TagIn1, TagIn2, TagOut>
  35. {};
  36. // If reversal is needed, perform it first
  37. template
  38. <
  39. typename Geometry1, typename Geometry2, typename GeometryOut,
  40. typename TagIn1, typename TagIn2, typename TagOut,
  41. bool Reverse1, bool Reverse2, bool ReverseOut
  42. >
  43. struct union_insert
  44. <
  45. Geometry1, Geometry2, GeometryOut,
  46. TagIn1, TagIn2, TagOut,
  47. true, true, true,
  48. Reverse1, Reverse2, ReverseOut,
  49. true
  50. >: union_insert<Geometry2, Geometry1, GeometryOut>
  51. {
  52. template <typename OutputIterator, typename Strategy>
  53. static inline OutputIterator apply(Geometry1 const& g1,
  54. Geometry2 const& g2, OutputIterator out,
  55. Strategy const& strategy)
  56. {
  57. return union_insert
  58. <
  59. Geometry2, Geometry1, GeometryOut
  60. >::apply(g2, g1, out, strategy);
  61. }
  62. };
  63. template
  64. <
  65. typename Geometry1, typename Geometry2, typename GeometryOut,
  66. typename TagIn1, typename TagIn2, typename TagOut,
  67. bool Reverse1, bool Reverse2, bool ReverseOut
  68. >
  69. struct union_insert
  70. <
  71. Geometry1, Geometry2, GeometryOut,
  72. TagIn1, TagIn2, TagOut,
  73. true, true, true,
  74. Reverse1, Reverse2, ReverseOut,
  75. false
  76. > : detail::overlay::overlay
  77. <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, GeometryOut, overlay_union>
  78. {};
  79. } // namespace dispatch
  80. #endif // DOXYGEN_NO_DISPATCH
  81. #ifndef DOXYGEN_NO_DETAIL
  82. namespace detail { namespace union_
  83. {
  84. template
  85. <
  86. typename GeometryOut,
  87. typename Geometry1, typename Geometry2,
  88. typename OutputIterator,
  89. typename Strategy
  90. >
  91. inline OutputIterator insert(Geometry1 const& geometry1,
  92. Geometry2 const& geometry2,
  93. OutputIterator out,
  94. Strategy const& strategy)
  95. {
  96. return dispatch::union_insert
  97. <
  98. Geometry1, Geometry2, GeometryOut
  99. >::apply(geometry1, geometry2, out, strategy);
  100. }
  101. /*!
  102. \brief_calc2{union} \brief_strategy
  103. \ingroup union
  104. \details \details_calc2{union_insert, spatial set theoretic union}
  105. \brief_strategy. details_insert{union}
  106. \tparam GeometryOut output geometry type, must be specified
  107. \tparam Geometry1 \tparam_geometry
  108. \tparam Geometry2 \tparam_geometry
  109. \tparam OutputIterator output iterator
  110. \tparam Strategy \tparam_strategy_overlay
  111. \param geometry1 \param_geometry
  112. \param geometry2 \param_geometry
  113. \param out \param_out{union}
  114. \param strategy \param_strategy{union}
  115. \return \return_out
  116. \qbk{distinguish,with strategy}
  117. */
  118. template
  119. <
  120. typename GeometryOut,
  121. typename Geometry1,
  122. typename Geometry2,
  123. typename OutputIterator,
  124. typename Strategy
  125. >
  126. inline OutputIterator union_insert(Geometry1 const& geometry1,
  127. Geometry2 const& geometry2,
  128. OutputIterator out,
  129. Strategy const& strategy)
  130. {
  131. concept::check<Geometry1 const>();
  132. concept::check<Geometry2 const>();
  133. concept::check<GeometryOut>();
  134. return detail::union_::insert<GeometryOut>(geometry1, geometry2, out, strategy);
  135. }
  136. /*!
  137. \brief_calc2{union}
  138. \ingroup union
  139. \details \details_calc2{union_insert, spatial set theoretic union}.
  140. \details_insert{union}
  141. \tparam GeometryOut output geometry type, must be specified
  142. \tparam Geometry1 \tparam_geometry
  143. \tparam Geometry2 \tparam_geometry
  144. \tparam OutputIterator output iterator
  145. \param geometry1 \param_geometry
  146. \param geometry2 \param_geometry
  147. \param out \param_out{union}
  148. \return \return_out
  149. */
  150. template
  151. <
  152. typename GeometryOut,
  153. typename Geometry1,
  154. typename Geometry2,
  155. typename OutputIterator
  156. >
  157. inline OutputIterator union_insert(Geometry1 const& geometry1,
  158. Geometry2 const& geometry2,
  159. OutputIterator out)
  160. {
  161. concept::check<Geometry1 const>();
  162. concept::check<Geometry2 const>();
  163. concept::check<GeometryOut>();
  164. typedef strategy_intersection
  165. <
  166. typename cs_tag<GeometryOut>::type,
  167. Geometry1,
  168. Geometry2,
  169. typename geometry::point_type<GeometryOut>::type
  170. > strategy;
  171. return union_insert<GeometryOut>(geometry1, geometry2, out, strategy());
  172. }
  173. }} // namespace detail::union_
  174. #endif // DOXYGEN_NO_DETAIL
  175. /*!
  176. \brief Combines two geometries which each other
  177. \ingroup union
  178. \details \details_calc2{union, spatial set theoretic union}.
  179. \tparam Geometry1 \tparam_geometry
  180. \tparam Geometry2 \tparam_geometry
  181. \tparam Collection output collection, either a multi-geometry,
  182. or a std::vector<Geometry> / std::deque<Geometry> etc
  183. \param geometry1 \param_geometry
  184. \param geometry2 \param_geometry
  185. \param output_collection the output collection
  186. \note Called union_ because union is a reserved word.
  187. \qbk{[include reference/algorithms/union.qbk]}
  188. */
  189. template
  190. <
  191. typename Geometry1,
  192. typename Geometry2,
  193. typename Collection
  194. >
  195. inline void union_(Geometry1 const& geometry1,
  196. Geometry2 const& geometry2,
  197. Collection& output_collection)
  198. {
  199. concept::check<Geometry1 const>();
  200. concept::check<Geometry2 const>();
  201. typedef typename boost::range_value<Collection>::type geometry_out;
  202. concept::check<geometry_out>();
  203. detail::union_::union_insert<geometry_out>(geometry1, geometry2,
  204. std::back_inserter(output_collection));
  205. }
  206. }} // namespace boost::geometry
  207. #endif // BOOST_GEOMETRY_ALGORITHMS_UNION_HPP