sym_difference.hpp 24 KB

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