sym_difference.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2015-2020.
  4. // Modifications copyright (c) 2015-2020 Oracle and/or its affiliates.
  5. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  6. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  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. #ifndef BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
  11. #define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
  12. #include <algorithm>
  13. #include <iterator>
  14. #include <vector>
  15. #include <boost/variant/apply_visitor.hpp>
  16. #include <boost/variant/static_visitor.hpp>
  17. #include <boost/variant/variant_fwd.hpp>
  18. #include <boost/geometry/algorithms/intersection.hpp>
  19. #include <boost/geometry/algorithms/union.hpp>
  20. #include <boost/geometry/geometries/multi_polygon.hpp>
  21. #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
  22. #include <boost/geometry/strategies/default_strategy.hpp>
  23. #include <boost/geometry/strategies/detail.hpp>
  24. #include <boost/geometry/strategies/relate/services.hpp>
  25. #include <boost/geometry/util/range.hpp>
  26. namespace boost { namespace geometry
  27. {
  28. #ifndef DOXYGEN_NO_DETAIL
  29. namespace detail { namespace sym_difference
  30. {
  31. template <typename GeometryOut>
  32. struct compute_difference
  33. {
  34. template
  35. <
  36. typename Geometry1,
  37. typename Geometry2,
  38. typename RobustPolicy,
  39. typename OutputIterator,
  40. typename Strategy
  41. >
  42. static inline OutputIterator apply(Geometry1 const& geometry1,
  43. Geometry2 const& geometry2,
  44. RobustPolicy const& robust_policy,
  45. OutputIterator out,
  46. Strategy const& strategy)
  47. {
  48. return geometry::dispatch::intersection_insert
  49. <
  50. Geometry1,
  51. Geometry2,
  52. GeometryOut,
  53. overlay_difference,
  54. geometry::detail::overlay::do_reverse
  55. <
  56. geometry::point_order<Geometry1>::value
  57. >::value,
  58. geometry::detail::overlay::do_reverse
  59. <
  60. geometry::point_order<Geometry2>::value, true
  61. >::value
  62. >::apply(geometry1, geometry2, robust_policy, out, strategy);
  63. }
  64. };
  65. template <typename GeometryOut, typename Geometry1, typename Geometry2>
  66. struct sym_difference_generic
  67. {
  68. template
  69. <
  70. typename RobustPolicy,
  71. typename OutputIterator,
  72. typename Strategy
  73. >
  74. static inline OutputIterator apply(Geometry1 const& geometry1,
  75. Geometry2 const& geometry2,
  76. RobustPolicy const& robust_policy,
  77. OutputIterator out,
  78. Strategy const& strategy)
  79. {
  80. out = compute_difference
  81. <
  82. GeometryOut
  83. >::apply(geometry1, geometry2, robust_policy, out, strategy);
  84. return compute_difference
  85. <
  86. GeometryOut
  87. >::apply(geometry2, geometry1, robust_policy, out, strategy);
  88. }
  89. };
  90. template <typename GeometryOut, typename Areal1, typename Areal2>
  91. struct sym_difference_areal_areal
  92. {
  93. template
  94. <
  95. typename RobustPolicy,
  96. typename OutputIterator,
  97. typename Strategy
  98. >
  99. static inline OutputIterator apply(Areal1 const& areal1,
  100. Areal2 const& areal2,
  101. RobustPolicy const& robust_policy,
  102. OutputIterator out,
  103. Strategy const& strategy)
  104. {
  105. typedef geometry::model::multi_polygon
  106. <
  107. GeometryOut
  108. > helper_geometry_type;
  109. helper_geometry_type diff12, diff21;
  110. std::back_insert_iterator<helper_geometry_type> oit12(diff12);
  111. std::back_insert_iterator<helper_geometry_type> oit21(diff21);
  112. compute_difference
  113. <
  114. GeometryOut
  115. >::apply(areal1, areal2, robust_policy, oit12, strategy);
  116. compute_difference
  117. <
  118. GeometryOut
  119. >::apply(areal2, areal1, robust_policy, oit21, strategy);
  120. return geometry::dispatch::union_insert
  121. <
  122. helper_geometry_type,
  123. helper_geometry_type,
  124. GeometryOut
  125. >::apply(diff12, diff21, robust_policy, out, strategy);
  126. }
  127. };
  128. template
  129. <
  130. typename GeometryOut,
  131. typename SingleTag,
  132. template <typename, typename, typename> class Algorithm
  133. >
  134. struct sym_difference_same_inputs_tupled_output
  135. {
  136. template
  137. <
  138. typename Geometry1,
  139. typename Geometry2,
  140. typename RobustPolicy,
  141. typename OutputIterator,
  142. typename Strategy
  143. >
  144. static inline OutputIterator apply(Geometry1 const& geometry1,
  145. Geometry2 const& geometry2,
  146. RobustPolicy const& robust_policy,
  147. OutputIterator out,
  148. Strategy const& strategy)
  149. {
  150. typedef typename geometry::detail::output_geometry_access
  151. <
  152. GeometryOut, SingleTag, SingleTag
  153. > access;
  154. access::get(out) = Algorithm
  155. <
  156. typename access::type, Geometry1, Geometry2
  157. >::apply(geometry1, geometry2, robust_policy, access::get(out), strategy);
  158. return out;
  159. }
  160. };
  161. template
  162. <
  163. typename GeometryOut,
  164. typename SingleTag1,
  165. typename SingleTag2,
  166. bool Reverse = (geometry::core_dispatch::top_dim<SingleTag1>::value
  167. > geometry::core_dispatch::top_dim<SingleTag2>::value)
  168. >
  169. struct sym_difference_different_inputs_tupled_output
  170. {
  171. template
  172. <
  173. typename Geometry1,
  174. typename Geometry2,
  175. typename RobustPolicy,
  176. typename OutputIterator,
  177. typename Strategy
  178. >
  179. static inline OutputIterator apply(Geometry1 const& geometry1,
  180. Geometry2 const& geometry2,
  181. RobustPolicy const& robust_policy,
  182. OutputIterator out,
  183. Strategy const& strategy)
  184. {
  185. return sym_difference_different_inputs_tupled_output
  186. <
  187. GeometryOut, SingleTag2, SingleTag1
  188. >::apply(geometry2, geometry1, robust_policy, out, strategy);
  189. }
  190. };
  191. template
  192. <
  193. typename GeometryOut,
  194. typename SingleTag1,
  195. typename SingleTag2
  196. >
  197. struct sym_difference_different_inputs_tupled_output
  198. <
  199. GeometryOut, SingleTag1, SingleTag2, false
  200. >
  201. {
  202. template
  203. <
  204. typename Geometry1,
  205. typename Geometry2,
  206. typename RobustPolicy,
  207. typename OutputIterator,
  208. typename Strategy
  209. >
  210. static inline OutputIterator apply(Geometry1 const& geometry1,
  211. Geometry2 const& geometry2,
  212. RobustPolicy const& robust_policy,
  213. OutputIterator out,
  214. Strategy const& strategy)
  215. {
  216. typedef typename geometry::detail::output_geometry_access
  217. <
  218. GeometryOut, SingleTag1, SingleTag1
  219. > access1;
  220. typedef typename geometry::detail::output_geometry_access
  221. <
  222. GeometryOut, SingleTag2, SingleTag2
  223. > access2;
  224. access1::get(out) = compute_difference
  225. <
  226. typename access1::type
  227. >::apply(geometry1, geometry2, robust_policy, access1::get(out), strategy);
  228. access2::get(out) = geometry::detail::convert_to_output
  229. <
  230. Geometry2,
  231. typename access2::type
  232. >::apply(geometry2, access2::get(out));
  233. return out;
  234. }
  235. };
  236. }} // namespace detail::sym_difference
  237. #endif // DOXYGEN_NO_DETAIL
  238. #ifndef DOXYGEN_NO_DISPATCH
  239. namespace dispatch
  240. {
  241. template
  242. <
  243. typename Geometry1,
  244. typename Geometry2,
  245. typename GeometryOut,
  246. typename TagIn1 = typename geometry::tag_cast
  247. <
  248. typename tag<Geometry1>::type, pointlike_tag, linear_tag, areal_tag
  249. >::type,
  250. typename TagIn2 = typename geometry::tag_cast
  251. <
  252. typename tag<Geometry2>::type, pointlike_tag, linear_tag, areal_tag
  253. >::type,
  254. typename TagOut = typename detail::setop_insert_output_tag<GeometryOut>::type
  255. >
  256. struct sym_difference_insert
  257. : detail::sym_difference::sym_difference_generic
  258. <
  259. GeometryOut, Geometry1, Geometry2
  260. >
  261. {};
  262. template
  263. <
  264. typename Areal1,
  265. typename Areal2,
  266. typename GeometryOut,
  267. typename TagOut
  268. >
  269. struct sym_difference_insert
  270. <
  271. Areal1, Areal2, GeometryOut,
  272. areal_tag, areal_tag, TagOut
  273. > : detail::sym_difference::sym_difference_areal_areal
  274. <
  275. GeometryOut, Areal1, Areal2
  276. >
  277. {};
  278. template
  279. <
  280. typename PointLike1,
  281. typename PointLike2,
  282. typename GeometryOut
  283. >
  284. struct sym_difference_insert
  285. <
  286. PointLike1, PointLike2, GeometryOut,
  287. pointlike_tag, pointlike_tag, detail::tupled_output_tag
  288. >
  289. : detail::expect_output<PointLike1, PointLike2, GeometryOut, point_tag>
  290. , detail::sym_difference::sym_difference_same_inputs_tupled_output
  291. <
  292. GeometryOut,
  293. point_tag,
  294. detail::sym_difference::sym_difference_generic
  295. >
  296. {};
  297. template
  298. <
  299. typename Linear1,
  300. typename Linear2,
  301. typename GeometryOut
  302. >
  303. struct sym_difference_insert
  304. <
  305. Linear1, Linear2, GeometryOut,
  306. linear_tag, linear_tag, detail::tupled_output_tag
  307. >
  308. : detail::expect_output<Linear1, Linear2, GeometryOut, linestring_tag>
  309. , detail::sym_difference::sym_difference_same_inputs_tupled_output
  310. <
  311. GeometryOut,
  312. linestring_tag,
  313. detail::sym_difference::sym_difference_generic
  314. >
  315. {};
  316. template
  317. <
  318. typename Areal1,
  319. typename Areal2,
  320. typename GeometryOut
  321. >
  322. struct sym_difference_insert
  323. <
  324. Areal1, Areal2, GeometryOut,
  325. areal_tag, areal_tag, detail::tupled_output_tag
  326. >
  327. : detail::expect_output<Areal1, Areal2, GeometryOut, polygon_tag>
  328. , detail::sym_difference::sym_difference_same_inputs_tupled_output
  329. <
  330. GeometryOut,
  331. polygon_tag,
  332. detail::sym_difference::sym_difference_areal_areal
  333. >
  334. {};
  335. template
  336. <
  337. typename Geometry1,
  338. typename Geometry2,
  339. typename GeometryOut,
  340. typename TagIn1,
  341. typename TagIn2
  342. >
  343. struct sym_difference_insert
  344. <
  345. Geometry1, Geometry2, GeometryOut,
  346. TagIn1, TagIn2, detail::tupled_output_tag
  347. >
  348. : detail::expect_output
  349. <
  350. Geometry1, Geometry2, GeometryOut,
  351. typename detail::single_tag_from_base_tag<TagIn1>::type,
  352. typename detail::single_tag_from_base_tag<TagIn2>::type
  353. >
  354. , detail::sym_difference::sym_difference_different_inputs_tupled_output
  355. <
  356. GeometryOut,
  357. typename detail::single_tag_from_base_tag<TagIn1>::type,
  358. typename detail::single_tag_from_base_tag<TagIn2>::type
  359. >
  360. {};
  361. } // namespace dispatch
  362. #endif // DOXYGEN_NO_DISPATCH
  363. #ifndef DOXYGEN_NO_DETAIL
  364. namespace detail { namespace sym_difference
  365. {
  366. /*!
  367. \brief \brief_calc2{symmetric difference} \brief_strategy
  368. \ingroup sym_difference
  369. \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
  370. \brief_strategy. \details_insert{sym_difference}
  371. \tparam GeometryOut output geometry type, must be specified
  372. \tparam Geometry1 \tparam_geometry
  373. \tparam Geometry2 \tparam_geometry
  374. \tparam Strategy \tparam_strategy_overlay
  375. \param geometry1 \param_geometry
  376. \param geometry2 \param_geometry
  377. \param out \param_out{difference}
  378. \param strategy \param_strategy{difference}
  379. \return \return_out
  380. \qbk{distinguish,with strategy}
  381. */
  382. template
  383. <
  384. typename GeometryOut,
  385. typename Geometry1,
  386. typename Geometry2,
  387. typename OutputIterator,
  388. typename Strategy
  389. >
  390. inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
  391. Geometry2 const& geometry2,
  392. OutputIterator out,
  393. Strategy const& strategy)
  394. {
  395. concepts::check<Geometry1 const>();
  396. concepts::check<Geometry2 const>();
  397. //concepts::check<GeometryOut>();
  398. geometry::detail::output_geometry_concept_check<GeometryOut>::apply();
  399. typedef typename geometry::rescale_overlay_policy_type
  400. <
  401. Geometry1,
  402. Geometry2,
  403. typename Strategy::cs_tag
  404. >::type rescale_policy_type;
  405. rescale_policy_type robust_policy
  406. = geometry::get_rescale_policy<rescale_policy_type>(
  407. geometry1, geometry2, strategy);
  408. return dispatch::sym_difference_insert
  409. <
  410. Geometry1, Geometry2, GeometryOut
  411. >::apply(geometry1, geometry2, robust_policy, out, strategy);
  412. }
  413. /*!
  414. \brief \brief_calc2{symmetric difference}
  415. \ingroup sym_difference
  416. \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
  417. \details_insert{sym_difference}
  418. \tparam GeometryOut output geometry type, must be specified
  419. \tparam Geometry1 \tparam_geometry
  420. \tparam Geometry2 \tparam_geometry
  421. \param geometry1 \param_geometry
  422. \param geometry2 \param_geometry
  423. \param out \param_out{difference}
  424. \return \return_out
  425. */
  426. template
  427. <
  428. typename GeometryOut,
  429. typename Geometry1,
  430. typename Geometry2,
  431. typename OutputIterator
  432. >
  433. inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
  434. Geometry2 const& geometry2, OutputIterator out)
  435. {
  436. typedef typename strategies::relate::services::default_strategy
  437. <
  438. Geometry1, Geometry2
  439. >::type strategy_type;
  440. return sym_difference_insert<GeometryOut>(geometry1, geometry2, out, strategy_type());
  441. }
  442. }} // namespace detail::sym_difference
  443. #endif // DOXYGEN_NO_DETAIL
  444. namespace resolve_strategy {
  445. template
  446. <
  447. typename Strategy,
  448. bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
  449. >
  450. struct sym_difference
  451. {
  452. template <typename Geometry1, typename Geometry2, typename Collection>
  453. static inline void apply(Geometry1 const& geometry1,
  454. Geometry2 const& geometry2,
  455. Collection & output_collection,
  456. Strategy const& strategy)
  457. {
  458. typedef typename geometry::detail::output_geometry_value
  459. <
  460. Collection
  461. >::type single_out;
  462. detail::sym_difference::sym_difference_insert<single_out>(
  463. geometry1, geometry2,
  464. geometry::detail::output_geometry_back_inserter(output_collection),
  465. strategy);
  466. }
  467. };
  468. template <typename Strategy>
  469. struct sym_difference<Strategy, false>
  470. {
  471. template <typename Geometry1, typename Geometry2, typename Collection>
  472. static inline void apply(Geometry1 const& geometry1,
  473. Geometry2 const& geometry2,
  474. Collection & output_collection,
  475. Strategy const& strategy)
  476. {
  477. using strategies::relate::services::strategy_converter;
  478. sym_difference
  479. <
  480. decltype(strategy_converter<Strategy>::get(strategy))
  481. >::apply(geometry1, geometry2, output_collection,
  482. strategy_converter<Strategy>::get(strategy));
  483. }
  484. };
  485. template <>
  486. struct sym_difference<default_strategy, false>
  487. {
  488. template <typename Geometry1, typename Geometry2, typename Collection>
  489. static inline void apply(Geometry1 const& geometry1,
  490. Geometry2 const& geometry2,
  491. Collection & output_collection,
  492. default_strategy)
  493. {
  494. typedef typename strategy::relate::services::default_strategy
  495. <
  496. Geometry1, Geometry2
  497. >::type strategy_type;
  498. sym_difference
  499. <
  500. strategy_type
  501. >::apply(geometry1, geometry2, output_collection, strategy_type());
  502. }
  503. };
  504. } // resolve_strategy
  505. namespace resolve_variant
  506. {
  507. template <typename Geometry1, typename Geometry2>
  508. struct sym_difference
  509. {
  510. template <typename Collection, typename Strategy>
  511. static inline void apply(Geometry1 const& geometry1,
  512. Geometry2 const& geometry2,
  513. Collection& output_collection,
  514. Strategy const& strategy)
  515. {
  516. resolve_strategy::sym_difference
  517. <
  518. Strategy
  519. >::apply(geometry1, geometry2, output_collection, strategy);
  520. }
  521. };
  522. template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
  523. struct sym_difference<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
  524. {
  525. template <typename Collection, typename Strategy>
  526. struct visitor: static_visitor<>
  527. {
  528. Geometry2 const& m_geometry2;
  529. Collection& m_output_collection;
  530. Strategy const& m_strategy;
  531. visitor(Geometry2 const& geometry2,
  532. Collection& output_collection,
  533. Strategy const& strategy)
  534. : m_geometry2(geometry2)
  535. , m_output_collection(output_collection)
  536. , m_strategy(strategy)
  537. {}
  538. template <typename Geometry1>
  539. void operator()(Geometry1 const& geometry1) const
  540. {
  541. sym_difference
  542. <
  543. Geometry1,
  544. Geometry2
  545. >::apply(geometry1, m_geometry2, m_output_collection, m_strategy);
  546. }
  547. };
  548. template <typename Collection, typename Strategy>
  549. static inline void
  550. apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
  551. Geometry2 const& geometry2,
  552. Collection& output_collection,
  553. Strategy const& strategy)
  554. {
  555. boost::apply_visitor(visitor<Collection, Strategy>(geometry2,
  556. output_collection,
  557. strategy),
  558. geometry1);
  559. }
  560. };
  561. template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  562. struct sym_difference<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  563. {
  564. template <typename Collection, typename Strategy>
  565. struct visitor: static_visitor<>
  566. {
  567. Geometry1 const& m_geometry1;
  568. Collection& m_output_collection;
  569. Strategy const& m_strategy;
  570. visitor(Geometry1 const& geometry1,
  571. Collection& output_collection,
  572. Strategy const& strategy)
  573. : m_geometry1(geometry1)
  574. , m_output_collection(output_collection)
  575. , m_strategy(strategy)
  576. {}
  577. template <typename Geometry2>
  578. void operator()(Geometry2 const& geometry2) const
  579. {
  580. sym_difference
  581. <
  582. Geometry1,
  583. Geometry2
  584. >::apply(m_geometry1, geometry2, m_output_collection, m_strategy);
  585. }
  586. };
  587. template <typename Collection, typename Strategy>
  588. static inline void
  589. apply(Geometry1 const& geometry1,
  590. variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
  591. Collection& output_collection,
  592. Strategy const& strategy)
  593. {
  594. boost::apply_visitor(visitor<Collection, Strategy>(geometry1,
  595. output_collection,
  596. strategy),
  597. geometry2);
  598. }
  599. };
  600. template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
  601. struct sym_difference<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
  602. {
  603. template <typename Collection, typename Strategy>
  604. struct visitor: static_visitor<>
  605. {
  606. Collection& m_output_collection;
  607. Strategy const& m_strategy;
  608. visitor(Collection& output_collection, Strategy const& strategy)
  609. : m_output_collection(output_collection)
  610. , m_strategy(strategy)
  611. {}
  612. template <typename Geometry1, typename Geometry2>
  613. void operator()(Geometry1 const& geometry1,
  614. Geometry2 const& geometry2) const
  615. {
  616. sym_difference
  617. <
  618. Geometry1,
  619. Geometry2
  620. >::apply(geometry1, geometry2, m_output_collection, m_strategy);
  621. }
  622. };
  623. template <typename Collection, typename Strategy>
  624. static inline void
  625. apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
  626. variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
  627. Collection& output_collection,
  628. Strategy const& strategy)
  629. {
  630. boost::apply_visitor(visitor<Collection, Strategy>(output_collection,
  631. strategy),
  632. geometry1, geometry2);
  633. }
  634. };
  635. } // namespace resolve_variant
  636. /*!
  637. \brief \brief_calc2{symmetric difference}
  638. \ingroup sym_difference
  639. \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
  640. \tparam Geometry1 \tparam_geometry
  641. \tparam Geometry2 \tparam_geometry
  642. \tparam Collection output collection, either a multi-geometry,
  643. or a std::vector<Geometry> / std::deque<Geometry> etc
  644. \tparam Strategy \tparam_strategy{Sym_difference}
  645. \param geometry1 \param_geometry
  646. \param geometry2 \param_geometry
  647. \param output_collection the output collection
  648. \param strategy \param_strategy{sym_difference}
  649. \qbk{distinguish,with strategy}
  650. \qbk{[include reference/algorithms/sym_difference.qbk]}
  651. */
  652. template
  653. <
  654. typename Geometry1,
  655. typename Geometry2,
  656. typename Collection,
  657. typename Strategy
  658. >
  659. inline void sym_difference(Geometry1 const& geometry1,
  660. Geometry2 const& geometry2,
  661. Collection& output_collection,
  662. Strategy const& strategy)
  663. {
  664. resolve_variant::sym_difference
  665. <
  666. Geometry1,
  667. Geometry2
  668. >::apply(geometry1, geometry2, output_collection, strategy);
  669. }
  670. /*!
  671. \brief \brief_calc2{symmetric difference}
  672. \ingroup sym_difference
  673. \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
  674. \tparam Geometry1 \tparam_geometry
  675. \tparam Geometry2 \tparam_geometry
  676. \tparam Collection output collection, either a multi-geometry,
  677. or a std::vector<Geometry> / std::deque<Geometry> etc
  678. \param geometry1 \param_geometry
  679. \param geometry2 \param_geometry
  680. \param output_collection the output collection
  681. \qbk{[include reference/algorithms/sym_difference.qbk]}
  682. */
  683. template
  684. <
  685. typename Geometry1,
  686. typename Geometry2,
  687. typename Collection
  688. >
  689. inline void sym_difference(Geometry1 const& geometry1,
  690. Geometry2 const& geometry2,
  691. Collection& output_collection)
  692. {
  693. resolve_variant::sym_difference
  694. <
  695. Geometry1,
  696. Geometry2
  697. >::apply(geometry1, geometry2, output_collection, default_strategy());
  698. }
  699. }} // namespace boost::geometry
  700. #endif // BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP