sym_difference.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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_SYM_DIFFERENCE_HPP
  7. #define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
  8. #include <algorithm>
  9. #include <boost/geometry/algorithms/intersection.hpp>
  10. namespace boost { namespace geometry
  11. {
  12. #ifndef DOXYGEN_NO_DETAIL
  13. namespace detail { namespace sym_difference
  14. {
  15. /*!
  16. \brief \brief_calc2{symmetric difference} \brief_strategy
  17. \ingroup sym_difference
  18. \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
  19. \brief_strategy. \details_insert{sym_difference}
  20. \tparam GeometryOut output geometry type, must be specified
  21. \tparam Geometry1 \tparam_geometry
  22. \tparam Geometry2 \tparam_geometry
  23. \tparam Strategy \tparam_strategy_overlay
  24. \param geometry1 \param_geometry
  25. \param geometry2 \param_geometry
  26. \param out \param_out{difference}
  27. \param strategy \param_strategy{difference}
  28. \return \return_out
  29. \qbk{distinguish,with strategy}
  30. */
  31. template
  32. <
  33. typename GeometryOut,
  34. typename Geometry1,
  35. typename Geometry2,
  36. typename OutputIterator,
  37. typename Strategy
  38. >
  39. inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
  40. Geometry2 const& geometry2, OutputIterator out,
  41. Strategy const& strategy)
  42. {
  43. concept::check<Geometry1 const>();
  44. concept::check<Geometry2 const>();
  45. concept::check<GeometryOut>();
  46. out = geometry::dispatch::intersection_insert
  47. <
  48. Geometry1, Geometry2,
  49. GeometryOut,
  50. overlay_difference,
  51. geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
  52. geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
  53. >::apply(geometry1, geometry2, out, strategy);
  54. out = geometry::dispatch::intersection_insert
  55. <
  56. Geometry2, Geometry1,
  57. GeometryOut,
  58. overlay_difference,
  59. geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
  60. geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, true>::value,
  61. geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
  62. >::apply(geometry2, geometry1, out, strategy);
  63. return out;
  64. }
  65. /*!
  66. \brief \brief_calc2{symmetric difference}
  67. \ingroup sym_difference
  68. \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
  69. \details_insert{sym_difference}
  70. \tparam GeometryOut output geometry type, must be specified
  71. \tparam Geometry1 \tparam_geometry
  72. \tparam Geometry2 \tparam_geometry
  73. \param geometry1 \param_geometry
  74. \param geometry2 \param_geometry
  75. \param out \param_out{difference}
  76. \return \return_out
  77. */
  78. template
  79. <
  80. typename GeometryOut,
  81. typename Geometry1,
  82. typename Geometry2,
  83. typename OutputIterator
  84. >
  85. inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
  86. Geometry2 const& geometry2, OutputIterator out)
  87. {
  88. concept::check<Geometry1 const>();
  89. concept::check<Geometry2 const>();
  90. concept::check<GeometryOut>();
  91. typedef strategy_intersection
  92. <
  93. typename cs_tag<GeometryOut>::type,
  94. Geometry1,
  95. Geometry2,
  96. typename geometry::point_type<GeometryOut>::type
  97. > strategy_type;
  98. return sym_difference_insert<GeometryOut>(geometry1, geometry2, out, strategy_type());
  99. }
  100. }} // namespace detail::sym_difference
  101. #endif // DOXYGEN_NO_DETAIL
  102. /*!
  103. \brief \brief_calc2{symmetric difference}
  104. \ingroup sym_difference
  105. \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
  106. \tparam Geometry1 \tparam_geometry
  107. \tparam Geometry2 \tparam_geometry
  108. \tparam Collection output collection, either a multi-geometry,
  109. or a std::vector<Geometry> / std::deque<Geometry> etc
  110. \param geometry1 \param_geometry
  111. \param geometry2 \param_geometry
  112. \param output_collection the output collection
  113. \qbk{[include reference/algorithms/sym_difference.qbk]}
  114. */
  115. template
  116. <
  117. typename Geometry1,
  118. typename Geometry2,
  119. typename Collection
  120. >
  121. inline void sym_difference(Geometry1 const& geometry1,
  122. Geometry2 const& geometry2, Collection& output_collection)
  123. {
  124. concept::check<Geometry1 const>();
  125. concept::check<Geometry2 const>();
  126. typedef typename boost::range_value<Collection>::type geometry_out;
  127. concept::check<geometry_out>();
  128. detail::sym_difference::sym_difference_insert<geometry_out>(
  129. geometry1, geometry2,
  130. std::back_inserter(output_collection));
  131. }
  132. }} // namespace boost::geometry
  133. #endif // BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP