intersection_insert.hpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555
  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 2014-2021.
  4. // Modifications copyright (c) 2014-2021 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_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
  12. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
  13. #include <cstddef>
  14. #include <deque>
  15. #include <type_traits>
  16. #include <boost/range/begin.hpp>
  17. #include <boost/range/end.hpp>
  18. #include <boost/range/size.hpp>
  19. #include <boost/geometry/algorithms/convert.hpp>
  20. #include <boost/geometry/algorithms/detail/point_on_border.hpp>
  21. #include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
  22. #include <boost/geometry/algorithms/detail/overlay/follow.hpp>
  23. #include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
  24. #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
  25. #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
  26. #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
  27. #include <boost/geometry/algorithms/detail/overlay/pointlike_areal.hpp>
  28. #include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
  29. #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
  30. #include <boost/geometry/algorithms/detail/overlay/range_in_geometry.hpp>
  31. #include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
  32. #include <boost/geometry/core/point_order.hpp>
  33. #include <boost/geometry/core/reverse_dispatch.hpp>
  34. #include <boost/geometry/core/static_assert.hpp>
  35. #include <boost/geometry/geometries/concepts/check.hpp>
  36. #include <boost/geometry/policies/robustness/rescale_policy_tags.hpp>
  37. #include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
  38. #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
  39. #include <boost/geometry/strategies/default_strategy.hpp>
  40. #include <boost/geometry/strategies/detail.hpp>
  41. #include <boost/geometry/strategies/relate/services.hpp>
  42. #include <boost/geometry/views/segment_view.hpp>
  43. #include <boost/geometry/views/detail/boundary_view.hpp>
  44. #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
  45. #include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
  46. #include <boost/geometry/io/wkt/wkt.hpp>
  47. #include <boost/geometry/util/for_each_with_index.hpp>
  48. #endif
  49. namespace boost { namespace geometry
  50. {
  51. #ifndef DOXYGEN_NO_DETAIL
  52. namespace detail { namespace intersection
  53. {
  54. template <typename PointOut>
  55. struct intersection_segment_segment_point
  56. {
  57. template
  58. <
  59. typename Segment1, typename Segment2,
  60. typename RobustPolicy,
  61. typename OutputIterator, typename Strategy
  62. >
  63. static inline OutputIterator apply(Segment1 const& segment1,
  64. Segment2 const& segment2,
  65. RobustPolicy const& ,
  66. OutputIterator out,
  67. Strategy const& strategy)
  68. {
  69. // Make sure this is only called with no rescaling
  70. BOOST_STATIC_ASSERT((std::is_same
  71. <
  72. no_rescale_policy_tag,
  73. typename rescale_policy_type<RobustPolicy>::type
  74. >::value));
  75. typedef typename point_type<PointOut>::type point_type;
  76. // Get the intersection point (or two points)
  77. typedef segment_intersection_points<point_type> intersection_return_type;
  78. typedef policies::relate::segments_intersection_points
  79. <
  80. intersection_return_type
  81. > policy_type;
  82. detail::segment_as_subrange<Segment1> sub_range1(segment1);
  83. detail::segment_as_subrange<Segment2> sub_range2(segment2);
  84. intersection_return_type
  85. is = strategy.relate().apply(sub_range1, sub_range2, policy_type());
  86. for (std::size_t i = 0; i < is.count; i++)
  87. {
  88. PointOut p;
  89. geometry::convert(is.intersections[i], p);
  90. *out++ = p;
  91. }
  92. return out;
  93. }
  94. };
  95. template <typename PointOut>
  96. struct intersection_linestring_linestring_point
  97. {
  98. template
  99. <
  100. typename Linestring1, typename Linestring2,
  101. typename RobustPolicy,
  102. typename OutputIterator,
  103. typename Strategy
  104. >
  105. static inline OutputIterator apply(Linestring1 const& linestring1,
  106. Linestring2 const& linestring2,
  107. RobustPolicy const& robust_policy,
  108. OutputIterator out,
  109. Strategy const& strategy)
  110. {
  111. // Make sure this is only called with no rescaling
  112. BOOST_STATIC_ASSERT((std::is_same
  113. <
  114. no_rescale_policy_tag,
  115. typename rescale_policy_type<RobustPolicy>::type
  116. >::value));
  117. typedef detail::overlay::turn_info<PointOut> turn_info;
  118. std::deque<turn_info> turns;
  119. geometry::get_intersection_points(linestring1, linestring2,
  120. robust_policy, turns, strategy);
  121. for (auto const& turn : turns)
  122. {
  123. PointOut p;
  124. geometry::convert(turn.point, p);
  125. *out++ = p;
  126. }
  127. return out;
  128. }
  129. };
  130. /*!
  131. \brief Version of linestring with an areal feature (polygon or multipolygon)
  132. */
  133. template
  134. <
  135. bool ReverseAreal,
  136. typename GeometryOut,
  137. overlay_type OverlayType,
  138. bool FollowIsolatedPoints
  139. >
  140. struct intersection_of_linestring_with_areal
  141. {
  142. #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
  143. template <typename Turn, typename Operation>
  144. static inline void debug_follow(Turn const& turn, Operation op,
  145. int index)
  146. {
  147. std::cout << index
  148. << " at " << op.seg_id
  149. << " meth: " << method_char(turn.method)
  150. << " op: " << operation_char(op.operation)
  151. << " vis: " << visited_char(op.visited)
  152. << " of: " << operation_char(turn.operations[0].operation)
  153. << operation_char(turn.operations[1].operation)
  154. << " " << geometry::wkt(turn.point)
  155. << std::endl;
  156. }
  157. template <typename Turn>
  158. static inline void debug_turn(Turn const& t, bool non_crossing)
  159. {
  160. std::cout << "checking turn @"
  161. << geometry::wkt(t.point)
  162. << "; " << method_char(t.method)
  163. << ":" << operation_char(t.operations[0].operation)
  164. << "/" << operation_char(t.operations[1].operation)
  165. << "; non-crossing? "
  166. << std::boolalpha << non_crossing << std::noboolalpha
  167. << std::endl;
  168. }
  169. #endif
  170. template <typename Linestring, typename Areal, typename Strategy, typename Turns>
  171. static inline bool simple_turns_analysis(Linestring const& linestring,
  172. Areal const& areal,
  173. Strategy const& strategy,
  174. Turns const& turns,
  175. int & inside_value)
  176. {
  177. using namespace overlay;
  178. bool found_continue = false;
  179. bool found_intersection = false;
  180. bool found_union = false;
  181. bool found_front = false;
  182. for (auto const& turn : turns)
  183. {
  184. method_type const method = turn.method;
  185. operation_type const op = turn.operations[0].operation;
  186. if (method == method_crosses)
  187. {
  188. return false;
  189. }
  190. else if (op == operation_intersection)
  191. {
  192. found_intersection = true;
  193. }
  194. else if (op == operation_union)
  195. {
  196. found_union = true;
  197. }
  198. else if (op == operation_continue)
  199. {
  200. found_continue = true;
  201. }
  202. if ((found_intersection || found_continue) && found_union)
  203. {
  204. return false;
  205. }
  206. if (turn.operations[0].position == position_front)
  207. {
  208. found_front = true;
  209. }
  210. }
  211. if (found_front)
  212. {
  213. if (found_intersection)
  214. {
  215. inside_value = 1; // inside
  216. }
  217. else if (found_union)
  218. {
  219. inside_value = -1; // outside
  220. }
  221. else // continue and blocked
  222. {
  223. inside_value = 0;
  224. }
  225. return true;
  226. }
  227. // if needed analyse points of a linestring
  228. // NOTE: range_in_geometry checks points of a linestring
  229. // until a point inside/outside areal is found
  230. // TODO: Could be replaced with point_in_geometry() because found_front is false
  231. inside_value = range_in_geometry(linestring, areal, strategy);
  232. if ( (found_intersection && inside_value == -1) // going in from outside
  233. || (found_continue && inside_value == -1) // going on boundary from outside
  234. || (found_union && inside_value == 1) ) // going out from inside
  235. {
  236. return false;
  237. }
  238. return true;
  239. }
  240. template
  241. <
  242. typename LineString, typename Areal,
  243. typename RobustPolicy,
  244. typename OutputIterator, typename Strategy
  245. >
  246. static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
  247. RobustPolicy const& robust_policy,
  248. OutputIterator out,
  249. Strategy const& strategy)
  250. {
  251. // Make sure this is only called with no rescaling
  252. BOOST_STATIC_ASSERT((std::is_same
  253. <
  254. no_rescale_policy_tag,
  255. typename rescale_policy_type<RobustPolicy>::type
  256. >::value));
  257. if (boost::size(linestring) == 0)
  258. {
  259. return out;
  260. }
  261. typedef detail::overlay::follow
  262. <
  263. GeometryOut,
  264. LineString,
  265. Areal,
  266. OverlayType,
  267. false, // do not remove spikes for linear geometries
  268. FollowIsolatedPoints
  269. > follower;
  270. typedef typename geometry::detail::output_geometry_access
  271. <
  272. GeometryOut, linestring_tag, linestring_tag
  273. > linear;
  274. typedef typename point_type
  275. <
  276. typename linear::type
  277. >::type point_type;
  278. typedef geometry::segment_ratio
  279. <
  280. typename coordinate_type<point_type>::type
  281. > ratio_type;
  282. typedef detail::overlay::turn_info
  283. <
  284. point_type,
  285. ratio_type,
  286. detail::overlay::turn_operation_linear
  287. <
  288. point_type,
  289. ratio_type
  290. >
  291. > turn_info;
  292. std::deque<turn_info> turns;
  293. detail::get_turns::no_interrupt_policy policy;
  294. typedef detail::overlay::get_turn_info_linear_areal
  295. <
  296. detail::overlay::assign_null_policy
  297. > turn_policy;
  298. dispatch::get_turns
  299. <
  300. typename geometry::tag<LineString>::type,
  301. typename geometry::tag<Areal>::type,
  302. LineString,
  303. Areal,
  304. false,
  305. (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
  306. turn_policy
  307. >::apply(0, linestring, 1, areal,
  308. strategy, robust_policy,
  309. turns, policy);
  310. int inside_value = 0;
  311. if (simple_turns_analysis(linestring, areal, strategy, turns, inside_value))
  312. {
  313. // No crossing the boundary, it is either
  314. // inside (interior + borders)
  315. // or outside (exterior + borders)
  316. // or on boundary
  317. // add linestring to the output if conditions are met
  318. if (follower::included(inside_value))
  319. {
  320. typename linear::type copy;
  321. geometry::convert(linestring, copy);
  322. *linear::get(out)++ = copy;
  323. }
  324. return out;
  325. }
  326. #if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
  327. for_each_with_index(turns, [](auto index, auto const& turn)
  328. {
  329. debug_follow(turn, turn.operations[0], index);
  330. });
  331. #endif
  332. return follower::apply
  333. (
  334. linestring, areal,
  335. geometry::detail::overlay::operation_intersection,
  336. turns, robust_policy, out, strategy
  337. );
  338. }
  339. };
  340. template <typename Turns, typename OutputIterator>
  341. inline OutputIterator intersection_output_turn_points(Turns const& turns,
  342. OutputIterator out)
  343. {
  344. for (auto const& turn : turns)
  345. {
  346. *out++ = turn.point;
  347. }
  348. return out;
  349. }
  350. template <typename PointOut>
  351. struct intersection_areal_areal_point
  352. {
  353. template
  354. <
  355. typename Geometry1, typename Geometry2,
  356. typename RobustPolicy,
  357. typename OutputIterator,
  358. typename Strategy
  359. >
  360. static inline OutputIterator apply(Geometry1 const& geometry1,
  361. Geometry2 const& geometry2,
  362. RobustPolicy const& robust_policy,
  363. OutputIterator out,
  364. Strategy const& strategy)
  365. {
  366. typedef detail::overlay::turn_info
  367. <
  368. PointOut,
  369. typename segment_ratio_type<PointOut, RobustPolicy>::type
  370. > turn_info;
  371. std::vector<turn_info> turns;
  372. detail::get_turns::no_interrupt_policy policy;
  373. geometry::get_turns
  374. <
  375. false, false, detail::overlay::assign_null_policy
  376. >(geometry1, geometry2, strategy, robust_policy, turns, policy);
  377. return intersection_output_turn_points(turns, out);
  378. }
  379. };
  380. template <typename PointOut>
  381. struct intersection_linear_areal_point
  382. {
  383. template
  384. <
  385. typename Geometry1, typename Geometry2,
  386. typename RobustPolicy,
  387. typename OutputIterator,
  388. typename Strategy
  389. >
  390. static inline OutputIterator apply(Geometry1 const& geometry1,
  391. Geometry2 const& geometry2,
  392. RobustPolicy const& robust_policy,
  393. OutputIterator out,
  394. Strategy const& strategy)
  395. {
  396. // Make sure this is only called with no rescaling
  397. BOOST_STATIC_ASSERT((std::is_same
  398. <
  399. no_rescale_policy_tag,
  400. typename rescale_policy_type<RobustPolicy>::type
  401. >::value));
  402. typedef geometry::segment_ratio<typename geometry::coordinate_type<PointOut>::type> ratio_type;
  403. typedef detail::overlay::turn_info
  404. <
  405. PointOut,
  406. ratio_type,
  407. detail::overlay::turn_operation_linear
  408. <
  409. PointOut,
  410. ratio_type
  411. >
  412. > turn_info;
  413. typedef detail::overlay::get_turn_info_linear_areal
  414. <
  415. detail::overlay::assign_null_policy
  416. > turn_policy;
  417. std::vector<turn_info> turns;
  418. detail::get_turns::no_interrupt_policy interrupt_policy;
  419. dispatch::get_turns
  420. <
  421. typename geometry::tag<Geometry1>::type,
  422. typename geometry::tag<Geometry2>::type,
  423. Geometry1,
  424. Geometry2,
  425. false,
  426. false,
  427. turn_policy
  428. >::apply(0, geometry1, 1, geometry2,
  429. strategy, robust_policy,
  430. turns, interrupt_policy);
  431. return intersection_output_turn_points(turns, out);
  432. }
  433. };
  434. template <typename PointOut>
  435. struct intersection_areal_linear_point
  436. {
  437. template
  438. <
  439. typename Geometry1, typename Geometry2,
  440. typename RobustPolicy,
  441. typename OutputIterator,
  442. typename Strategy
  443. >
  444. static inline OutputIterator apply(Geometry1 const& geometry1,
  445. Geometry2 const& geometry2,
  446. RobustPolicy const& robust_policy,
  447. OutputIterator out,
  448. Strategy const& strategy)
  449. {
  450. return intersection_linear_areal_point
  451. <
  452. PointOut
  453. >::apply(geometry2, geometry1, robust_policy, out, strategy);
  454. }
  455. };
  456. }} // namespace detail::intersection
  457. #endif // DOXYGEN_NO_DETAIL
  458. #ifndef DOXYGEN_NO_DISPATCH
  459. namespace dispatch
  460. {
  461. template
  462. <
  463. // real types
  464. typename Geometry1,
  465. typename Geometry2,
  466. typename GeometryOut,
  467. overlay_type OverlayType,
  468. // orientation
  469. bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
  470. bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
  471. // tag dispatching:
  472. typename TagIn1 = typename geometry::tag<Geometry1>::type,
  473. typename TagIn2 = typename geometry::tag<Geometry2>::type,
  474. typename TagOut = typename detail::setop_insert_output_tag<GeometryOut>::type,
  475. // metafunction finetuning helpers:
  476. typename CastedTagIn1 = typename geometry::tag_cast<TagIn1, areal_tag, linear_tag, pointlike_tag>::type,
  477. typename CastedTagIn2 = typename geometry::tag_cast<TagIn2, areal_tag, linear_tag, pointlike_tag>::type,
  478. typename CastedTagOut = typename geometry::tag_cast<TagOut, areal_tag, linear_tag, pointlike_tag>::type
  479. >
  480. struct intersection_insert
  481. {
  482. BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
  483. "Not or not yet implemented for these Geometry types or their order.",
  484. Geometry1, Geometry2, GeometryOut,
  485. std::integral_constant<overlay_type, OverlayType>);
  486. };
  487. template
  488. <
  489. typename Geometry1, typename Geometry2,
  490. typename GeometryOut,
  491. overlay_type OverlayType,
  492. bool Reverse1, bool Reverse2,
  493. typename TagIn1, typename TagIn2, typename TagOut
  494. >
  495. struct intersection_insert
  496. <
  497. Geometry1, Geometry2,
  498. GeometryOut,
  499. OverlayType,
  500. Reverse1, Reverse2,
  501. TagIn1, TagIn2, TagOut,
  502. areal_tag, areal_tag, areal_tag
  503. > : detail::overlay::overlay
  504. <
  505. Geometry1, Geometry2, Reverse1, Reverse2,
  506. detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
  507. GeometryOut, OverlayType
  508. >
  509. {};
  510. // Any areal type with box:
  511. template
  512. <
  513. typename Geometry, typename Box,
  514. typename GeometryOut,
  515. overlay_type OverlayType,
  516. bool Reverse1, bool Reverse2,
  517. typename TagIn, typename TagOut
  518. >
  519. struct intersection_insert
  520. <
  521. Geometry, Box,
  522. GeometryOut,
  523. OverlayType,
  524. Reverse1, Reverse2,
  525. TagIn, box_tag, TagOut,
  526. areal_tag, areal_tag, areal_tag
  527. > : detail::overlay::overlay
  528. <
  529. Geometry, Box, Reverse1, Reverse2,
  530. detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
  531. GeometryOut, OverlayType
  532. >
  533. {};
  534. template
  535. <
  536. typename Segment1, typename Segment2,
  537. typename GeometryOut,
  538. overlay_type OverlayType,
  539. bool Reverse1, bool Reverse2
  540. >
  541. struct intersection_insert
  542. <
  543. Segment1, Segment2,
  544. GeometryOut,
  545. OverlayType,
  546. Reverse1, Reverse2,
  547. segment_tag, segment_tag, point_tag,
  548. linear_tag, linear_tag, pointlike_tag
  549. > : detail::intersection::intersection_segment_segment_point<GeometryOut>
  550. {};
  551. template
  552. <
  553. typename Linestring1, typename Linestring2,
  554. typename GeometryOut,
  555. overlay_type OverlayType,
  556. bool Reverse1, bool Reverse2
  557. >
  558. struct intersection_insert
  559. <
  560. Linestring1, Linestring2,
  561. GeometryOut,
  562. OverlayType,
  563. Reverse1, Reverse2,
  564. linestring_tag, linestring_tag, point_tag,
  565. linear_tag, linear_tag, pointlike_tag
  566. > : detail::intersection::intersection_linestring_linestring_point<GeometryOut>
  567. {};
  568. template
  569. <
  570. typename Linestring, typename Box,
  571. typename GeometryOut,
  572. bool Reverse1, bool Reverse2
  573. >
  574. struct intersection_insert
  575. <
  576. Linestring, Box,
  577. GeometryOut,
  578. overlay_intersection,
  579. Reverse1, Reverse2,
  580. linestring_tag, box_tag, linestring_tag,
  581. linear_tag, areal_tag, linear_tag
  582. >
  583. {
  584. template <typename RobustPolicy, typename OutputIterator, typename Strategy>
  585. static inline OutputIterator apply(Linestring const& linestring,
  586. Box const& box,
  587. RobustPolicy const& robust_policy,
  588. OutputIterator out, Strategy const& )
  589. {
  590. typedef typename point_type<GeometryOut>::type point_type;
  591. strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
  592. return detail::intersection::clip_range_with_box
  593. <GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
  594. }
  595. };
  596. template
  597. <
  598. typename Linestring, typename Polygon,
  599. typename GeometryOut,
  600. overlay_type OverlayType,
  601. bool ReverseLinestring, bool ReversePolygon
  602. >
  603. struct intersection_insert
  604. <
  605. Linestring, Polygon,
  606. GeometryOut,
  607. OverlayType,
  608. ReverseLinestring, ReversePolygon,
  609. linestring_tag, polygon_tag, linestring_tag,
  610. linear_tag, areal_tag, linear_tag
  611. > : detail::intersection::intersection_of_linestring_with_areal
  612. <
  613. ReversePolygon,
  614. GeometryOut,
  615. OverlayType,
  616. false
  617. >
  618. {};
  619. template
  620. <
  621. typename Linestring, typename Ring,
  622. typename GeometryOut,
  623. overlay_type OverlayType,
  624. bool ReverseLinestring, bool ReverseRing
  625. >
  626. struct intersection_insert
  627. <
  628. Linestring, Ring,
  629. GeometryOut,
  630. OverlayType,
  631. ReverseLinestring, ReverseRing,
  632. linestring_tag, ring_tag, linestring_tag,
  633. linear_tag, areal_tag, linear_tag
  634. > : detail::intersection::intersection_of_linestring_with_areal
  635. <
  636. ReverseRing,
  637. GeometryOut,
  638. OverlayType,
  639. false
  640. >
  641. {};
  642. template
  643. <
  644. typename Segment, typename Box,
  645. typename GeometryOut,
  646. overlay_type OverlayType,
  647. bool Reverse1, bool Reverse2
  648. >
  649. struct intersection_insert
  650. <
  651. Segment, Box,
  652. GeometryOut,
  653. OverlayType,
  654. Reverse1, Reverse2,
  655. segment_tag, box_tag, linestring_tag,
  656. linear_tag, areal_tag, linear_tag
  657. >
  658. {
  659. template <typename RobustPolicy, typename OutputIterator, typename Strategy>
  660. static inline OutputIterator apply(Segment const& segment,
  661. Box const& box,
  662. RobustPolicy const& robust_policy,
  663. OutputIterator out, Strategy const& )
  664. {
  665. geometry::segment_view<Segment> range(segment);
  666. typedef typename point_type<GeometryOut>::type point_type;
  667. strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
  668. return detail::intersection::clip_range_with_box
  669. <GeometryOut>(box, range, robust_policy, out, lb_strategy);
  670. }
  671. };
  672. template
  673. <
  674. typename Geometry1, typename Geometry2,
  675. typename PointOut,
  676. overlay_type OverlayType,
  677. bool Reverse1, bool Reverse2,
  678. typename Tag1, typename Tag2
  679. >
  680. struct intersection_insert
  681. <
  682. Geometry1, Geometry2,
  683. PointOut,
  684. OverlayType,
  685. Reverse1, Reverse2,
  686. Tag1, Tag2, point_tag,
  687. areal_tag, areal_tag, pointlike_tag
  688. >
  689. : public detail::intersection::intersection_areal_areal_point
  690. <
  691. PointOut
  692. >
  693. {};
  694. template
  695. <
  696. typename Geometry1, typename Geometry2,
  697. typename PointOut,
  698. overlay_type OverlayType,
  699. bool Reverse1, bool Reverse2,
  700. typename Tag1, typename Tag2
  701. >
  702. struct intersection_insert
  703. <
  704. Geometry1, Geometry2,
  705. PointOut,
  706. OverlayType,
  707. Reverse1, Reverse2,
  708. Tag1, Tag2, point_tag,
  709. linear_tag, areal_tag, pointlike_tag
  710. >
  711. : public detail::intersection::intersection_linear_areal_point
  712. <
  713. PointOut
  714. >
  715. {};
  716. template
  717. <
  718. typename Geometry1, typename Geometry2,
  719. typename PointOut,
  720. overlay_type OverlayType,
  721. bool Reverse1, bool Reverse2,
  722. typename Tag1, typename Tag2
  723. >
  724. struct intersection_insert
  725. <
  726. Geometry1, Geometry2,
  727. PointOut,
  728. OverlayType,
  729. Reverse1, Reverse2,
  730. Tag1, Tag2, point_tag,
  731. areal_tag, linear_tag, pointlike_tag
  732. >
  733. : public detail::intersection::intersection_areal_linear_point
  734. <
  735. PointOut
  736. >
  737. {};
  738. template
  739. <
  740. typename Geometry1, typename Geometry2, typename GeometryOut,
  741. overlay_type OverlayType,
  742. bool Reverse1, bool Reverse2
  743. >
  744. struct intersection_insert_reversed
  745. {
  746. template <typename RobustPolicy, typename OutputIterator, typename Strategy>
  747. static inline OutputIterator apply(Geometry1 const& g1,
  748. Geometry2 const& g2,
  749. RobustPolicy const& robust_policy,
  750. OutputIterator out,
  751. Strategy const& strategy)
  752. {
  753. return intersection_insert
  754. <
  755. Geometry2, Geometry1, GeometryOut,
  756. OverlayType,
  757. Reverse2, Reverse1
  758. >::apply(g2, g1, robust_policy, out, strategy);
  759. }
  760. };
  761. // dispatch for intersection(areal, areal, linear)
  762. template
  763. <
  764. typename Geometry1, typename Geometry2,
  765. typename LinestringOut,
  766. bool Reverse1, bool Reverse2,
  767. typename Tag1, typename Tag2
  768. >
  769. struct intersection_insert
  770. <
  771. Geometry1, Geometry2,
  772. LinestringOut,
  773. overlay_intersection,
  774. Reverse1, Reverse2,
  775. Tag1, Tag2, linestring_tag,
  776. areal_tag, areal_tag, linear_tag
  777. >
  778. {
  779. template
  780. <
  781. typename RobustPolicy, typename OutputIterator, typename Strategy
  782. >
  783. static inline OutputIterator apply(Geometry1 const& geometry1,
  784. Geometry2 const& geometry2,
  785. RobustPolicy const& robust_policy,
  786. OutputIterator oit,
  787. Strategy const& strategy)
  788. {
  789. detail::boundary_view<Geometry1 const> view1(geometry1);
  790. detail::boundary_view<Geometry2 const> view2(geometry2);
  791. return detail::overlay::linear_linear_linestring
  792. <
  793. detail::boundary_view<Geometry1 const>,
  794. detail::boundary_view<Geometry2 const>,
  795. LinestringOut,
  796. overlay_intersection
  797. >::apply(view1, view2, robust_policy, oit, strategy);
  798. }
  799. };
  800. // dispatch for difference/intersection of linear geometries
  801. template
  802. <
  803. typename Linear1, typename Linear2, typename LineStringOut,
  804. overlay_type OverlayType,
  805. bool Reverse1, bool Reverse2,
  806. typename TagIn1, typename TagIn2
  807. >
  808. struct intersection_insert
  809. <
  810. Linear1, Linear2, LineStringOut, OverlayType,
  811. Reverse1, Reverse2,
  812. TagIn1, TagIn2, linestring_tag,
  813. linear_tag, linear_tag, linear_tag
  814. > : detail::overlay::linear_linear_linestring
  815. <
  816. Linear1, Linear2, LineStringOut, OverlayType
  817. >
  818. {};
  819. template
  820. <
  821. typename Linear1, typename Linear2, typename TupledOut,
  822. overlay_type OverlayType,
  823. bool Reverse1, bool Reverse2,
  824. typename TagIn1, typename TagIn2
  825. >
  826. struct intersection_insert
  827. <
  828. Linear1, Linear2, TupledOut, OverlayType,
  829. Reverse1, Reverse2,
  830. TagIn1, TagIn2, detail::tupled_output_tag,
  831. linear_tag, linear_tag, detail::tupled_output_tag
  832. >
  833. : detail::expect_output
  834. <
  835. Linear1, Linear2, TupledOut,
  836. // NOTE: points can be the result only in case of intersection.
  837. std::conditional_t
  838. <
  839. (OverlayType == overlay_intersection),
  840. point_tag,
  841. void
  842. >,
  843. linestring_tag
  844. >
  845. {
  846. // NOTE: The order of geometries in TupledOut tuple/pair must correspond to the order
  847. // iterators in OutputIterators tuple/pair.
  848. template
  849. <
  850. typename RobustPolicy, typename OutputIterators, typename Strategy
  851. >
  852. static inline OutputIterators apply(Linear1 const& linear1,
  853. Linear2 const& linear2,
  854. RobustPolicy const& robust_policy,
  855. OutputIterators oit,
  856. Strategy const& strategy)
  857. {
  858. return detail::overlay::linear_linear_linestring
  859. <
  860. Linear1, Linear2, TupledOut, OverlayType
  861. >::apply(linear1, linear2, robust_policy, oit, strategy);
  862. }
  863. };
  864. // dispatch for difference/intersection of point-like geometries
  865. template
  866. <
  867. typename Point1, typename Point2, typename PointOut,
  868. overlay_type OverlayType,
  869. bool Reverse1, bool Reverse2
  870. >
  871. struct intersection_insert
  872. <
  873. Point1, Point2, PointOut, OverlayType,
  874. Reverse1, Reverse2,
  875. point_tag, point_tag, point_tag,
  876. pointlike_tag, pointlike_tag, pointlike_tag
  877. > : detail::overlay::point_point_point
  878. <
  879. Point1, Point2, PointOut, OverlayType
  880. >
  881. {};
  882. template
  883. <
  884. typename MultiPoint, typename Point, typename PointOut,
  885. overlay_type OverlayType,
  886. bool Reverse1, bool Reverse2
  887. >
  888. struct intersection_insert
  889. <
  890. MultiPoint, Point, PointOut, OverlayType,
  891. Reverse1, Reverse2,
  892. multi_point_tag, point_tag, point_tag,
  893. pointlike_tag, pointlike_tag, pointlike_tag
  894. > : detail::overlay::multipoint_point_point
  895. <
  896. MultiPoint, Point, PointOut, OverlayType
  897. >
  898. {};
  899. template
  900. <
  901. typename Point, typename MultiPoint, typename PointOut,
  902. overlay_type OverlayType,
  903. bool Reverse1, bool Reverse2
  904. >
  905. struct intersection_insert
  906. <
  907. Point, MultiPoint, PointOut, OverlayType,
  908. Reverse1, Reverse2,
  909. point_tag, multi_point_tag, point_tag,
  910. pointlike_tag, pointlike_tag, pointlike_tag
  911. > : detail::overlay::point_multipoint_point
  912. <
  913. Point, MultiPoint, PointOut, OverlayType
  914. >
  915. {};
  916. template
  917. <
  918. typename MultiPoint1, typename MultiPoint2, typename PointOut,
  919. overlay_type OverlayType,
  920. bool Reverse1, bool Reverse2
  921. >
  922. struct intersection_insert
  923. <
  924. MultiPoint1, MultiPoint2, PointOut, OverlayType,
  925. Reverse1, Reverse2,
  926. multi_point_tag, multi_point_tag, point_tag,
  927. pointlike_tag, pointlike_tag, pointlike_tag
  928. > : detail::overlay::multipoint_multipoint_point
  929. <
  930. MultiPoint1, MultiPoint2, PointOut, OverlayType
  931. >
  932. {};
  933. template
  934. <
  935. typename PointLike1, typename PointLike2, typename TupledOut,
  936. overlay_type OverlayType,
  937. bool Reverse1, bool Reverse2,
  938. typename TagIn1, typename TagIn2
  939. >
  940. struct intersection_insert
  941. <
  942. PointLike1, PointLike2, TupledOut, OverlayType,
  943. Reverse1, Reverse2,
  944. TagIn1, TagIn2, detail::tupled_output_tag,
  945. pointlike_tag, pointlike_tag, detail::tupled_output_tag
  946. >
  947. : detail::expect_output<PointLike1, PointLike2, TupledOut, point_tag>
  948. {
  949. // NOTE: The order of geometries in TupledOut tuple/pair must correspond to the order
  950. // of iterators in OutputIterators tuple/pair.
  951. template
  952. <
  953. typename RobustPolicy, typename OutputIterators, typename Strategy
  954. >
  955. static inline OutputIterators apply(PointLike1 const& pointlike1,
  956. PointLike2 const& pointlike2,
  957. RobustPolicy const& robust_policy,
  958. OutputIterators oits,
  959. Strategy const& strategy)
  960. {
  961. namespace bgt = boost::geometry::tuples;
  962. static const bool out_point_index = bgt::find_index_if
  963. <
  964. TupledOut, geometry::detail::is_tag_same_as_pred<point_tag>::template pred
  965. >::value;
  966. bgt::get<out_point_index>(oits) = intersection_insert
  967. <
  968. PointLike1, PointLike2,
  969. typename bgt::element
  970. <
  971. out_point_index, TupledOut
  972. >::type,
  973. OverlayType
  974. >::apply(pointlike1, pointlike2, robust_policy,
  975. bgt::get<out_point_index>(oits),
  976. strategy);
  977. return oits;
  978. }
  979. };
  980. // dispatch for difference/intersection of pointlike-linear geometries
  981. template
  982. <
  983. typename Point, typename Linear, typename PointOut,
  984. overlay_type OverlayType,
  985. bool Reverse1, bool Reverse2,
  986. typename Tag
  987. >
  988. struct intersection_insert
  989. <
  990. Point, Linear, PointOut, OverlayType,
  991. Reverse1, Reverse2,
  992. point_tag, Tag, point_tag,
  993. pointlike_tag, linear_tag, pointlike_tag
  994. > : detail_dispatch::overlay::pointlike_linear_point
  995. <
  996. Point, Linear, PointOut, OverlayType,
  997. point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
  998. >
  999. {};
  1000. template
  1001. <
  1002. typename MultiPoint, typename Linear, typename PointOut,
  1003. overlay_type OverlayType,
  1004. bool Reverse1, bool Reverse2,
  1005. typename Tag
  1006. >
  1007. struct intersection_insert
  1008. <
  1009. MultiPoint, Linear, PointOut, OverlayType,
  1010. Reverse1, Reverse2,
  1011. multi_point_tag, Tag, point_tag,
  1012. pointlike_tag, linear_tag, pointlike_tag
  1013. > : detail_dispatch::overlay::pointlike_linear_point
  1014. <
  1015. MultiPoint, Linear, PointOut, OverlayType,
  1016. multi_point_tag,
  1017. typename tag_cast<Tag, segment_tag, linear_tag>::type
  1018. >
  1019. {};
  1020. // This specialization is needed because intersection() reverses the arguments
  1021. // for MultiPoint/Linestring combination.
  1022. template
  1023. <
  1024. typename Linestring, typename MultiPoint, typename PointOut,
  1025. bool Reverse1, bool Reverse2
  1026. >
  1027. struct intersection_insert
  1028. <
  1029. Linestring, MultiPoint, PointOut, overlay_intersection,
  1030. Reverse1, Reverse2,
  1031. linestring_tag, multi_point_tag, point_tag,
  1032. linear_tag, pointlike_tag, pointlike_tag
  1033. >
  1034. {
  1035. template <typename RobustPolicy, typename OutputIterator, typename Strategy>
  1036. static inline OutputIterator apply(Linestring const& linestring,
  1037. MultiPoint const& multipoint,
  1038. RobustPolicy const& robust_policy,
  1039. OutputIterator out,
  1040. Strategy const& strategy)
  1041. {
  1042. return detail_dispatch::overlay::pointlike_linear_point
  1043. <
  1044. MultiPoint, Linestring, PointOut, overlay_intersection,
  1045. multi_point_tag, linear_tag
  1046. >::apply(multipoint, linestring, robust_policy, out, strategy);
  1047. }
  1048. };
  1049. template
  1050. <
  1051. typename PointLike, typename Linear, typename TupledOut,
  1052. overlay_type OverlayType,
  1053. bool Reverse1, bool Reverse2,
  1054. typename TagIn1, typename TagIn2
  1055. >
  1056. struct intersection_insert
  1057. <
  1058. PointLike, Linear, TupledOut, OverlayType,
  1059. Reverse1, Reverse2,
  1060. TagIn1, TagIn2, detail::tupled_output_tag,
  1061. pointlike_tag, linear_tag, detail::tupled_output_tag
  1062. >
  1063. // Reuse the implementation for PointLike/PointLike.
  1064. : intersection_insert
  1065. <
  1066. PointLike, Linear, TupledOut, OverlayType,
  1067. Reverse1, Reverse2,
  1068. TagIn1, TagIn2, detail::tupled_output_tag,
  1069. pointlike_tag, pointlike_tag, detail::tupled_output_tag
  1070. >
  1071. {};
  1072. // This specialization is needed because intersection() reverses the arguments
  1073. // for MultiPoint/Linestring combination.
  1074. template
  1075. <
  1076. typename Linestring, typename MultiPoint, typename TupledOut,
  1077. bool Reverse1, bool Reverse2
  1078. >
  1079. struct intersection_insert
  1080. <
  1081. Linestring, MultiPoint, TupledOut, overlay_intersection,
  1082. Reverse1, Reverse2,
  1083. linestring_tag, multi_point_tag, detail::tupled_output_tag,
  1084. linear_tag, pointlike_tag, detail::tupled_output_tag
  1085. >
  1086. {
  1087. template <typename RobustPolicy, typename OutputIterators, typename Strategy>
  1088. static inline OutputIterators apply(Linestring const& linestring,
  1089. MultiPoint const& multipoint,
  1090. RobustPolicy const& robust_policy,
  1091. OutputIterators out,
  1092. Strategy const& strategy)
  1093. {
  1094. return intersection_insert
  1095. <
  1096. MultiPoint, Linestring, TupledOut, overlay_intersection
  1097. >::apply(multipoint, linestring, robust_policy, out, strategy);
  1098. }
  1099. };
  1100. // dispatch for difference/intersection of pointlike-areal geometries
  1101. template
  1102. <
  1103. typename Point, typename Areal, typename PointOut,
  1104. overlay_type OverlayType,
  1105. bool Reverse1, bool Reverse2,
  1106. typename ArealTag
  1107. >
  1108. struct intersection_insert
  1109. <
  1110. Point, Areal, PointOut, OverlayType,
  1111. Reverse1, Reverse2,
  1112. point_tag, ArealTag, point_tag,
  1113. pointlike_tag, areal_tag, pointlike_tag
  1114. > : detail_dispatch::overlay::pointlike_areal_point
  1115. <
  1116. Point, Areal, PointOut, OverlayType,
  1117. point_tag, ArealTag
  1118. >
  1119. {};
  1120. template
  1121. <
  1122. typename MultiPoint, typename Areal, typename PointOut,
  1123. overlay_type OverlayType,
  1124. bool Reverse1, bool Reverse2,
  1125. typename ArealTag
  1126. >
  1127. struct intersection_insert
  1128. <
  1129. MultiPoint, Areal, PointOut, OverlayType,
  1130. Reverse1, Reverse2,
  1131. multi_point_tag, ArealTag, point_tag,
  1132. pointlike_tag, areal_tag, pointlike_tag
  1133. > : detail_dispatch::overlay::pointlike_areal_point
  1134. <
  1135. MultiPoint, Areal, PointOut, OverlayType,
  1136. multi_point_tag, ArealTag
  1137. >
  1138. {};
  1139. // This specialization is needed because intersection() reverses the arguments
  1140. // for MultiPoint/Ring and MultiPoint/Polygon combinations.
  1141. template
  1142. <
  1143. typename Areal, typename MultiPoint, typename PointOut,
  1144. bool Reverse1, bool Reverse2,
  1145. typename ArealTag
  1146. >
  1147. struct intersection_insert
  1148. <
  1149. Areal, MultiPoint, PointOut, overlay_intersection,
  1150. Reverse1, Reverse2,
  1151. ArealTag, multi_point_tag, point_tag,
  1152. areal_tag, pointlike_tag, pointlike_tag
  1153. >
  1154. {
  1155. template <typename RobustPolicy, typename OutputIterator, typename Strategy>
  1156. static inline OutputIterator apply(Areal const& areal,
  1157. MultiPoint const& multipoint,
  1158. RobustPolicy const& robust_policy,
  1159. OutputIterator out,
  1160. Strategy const& strategy)
  1161. {
  1162. return detail_dispatch::overlay::pointlike_areal_point
  1163. <
  1164. MultiPoint, Areal, PointOut, overlay_intersection,
  1165. multi_point_tag, ArealTag
  1166. >::apply(multipoint, areal, robust_policy, out, strategy);
  1167. }
  1168. };
  1169. template
  1170. <
  1171. typename PointLike, typename Areal, typename TupledOut,
  1172. overlay_type OverlayType,
  1173. bool Reverse1, bool Reverse2,
  1174. typename TagIn1, typename TagIn2
  1175. >
  1176. struct intersection_insert
  1177. <
  1178. PointLike, Areal, TupledOut, OverlayType,
  1179. Reverse1, Reverse2,
  1180. TagIn1, TagIn2, detail::tupled_output_tag,
  1181. pointlike_tag, areal_tag, detail::tupled_output_tag
  1182. >
  1183. // Reuse the implementation for PointLike/PointLike.
  1184. : intersection_insert
  1185. <
  1186. PointLike, Areal, TupledOut, OverlayType,
  1187. Reverse1, Reverse2,
  1188. TagIn1, TagIn2, detail::tupled_output_tag,
  1189. pointlike_tag, pointlike_tag, detail::tupled_output_tag
  1190. >
  1191. {};
  1192. // This specialization is needed because intersection() reverses the arguments
  1193. // for MultiPoint/Ring and MultiPoint/Polygon combinations.
  1194. template
  1195. <
  1196. typename Areal, typename MultiPoint, typename TupledOut,
  1197. bool Reverse1, bool Reverse2,
  1198. typename TagIn1
  1199. >
  1200. struct intersection_insert
  1201. <
  1202. Areal, MultiPoint, TupledOut, overlay_intersection,
  1203. Reverse1, Reverse2,
  1204. TagIn1, multi_point_tag, detail::tupled_output_tag,
  1205. areal_tag, pointlike_tag, detail::tupled_output_tag
  1206. >
  1207. {
  1208. template <typename RobustPolicy, typename OutputIterators, typename Strategy>
  1209. static inline OutputIterators apply(Areal const& areal,
  1210. MultiPoint const& multipoint,
  1211. RobustPolicy const& robust_policy,
  1212. OutputIterators out,
  1213. Strategy const& strategy)
  1214. {
  1215. return intersection_insert
  1216. <
  1217. MultiPoint, Areal, TupledOut, overlay_intersection
  1218. >::apply(multipoint, areal, robust_policy, out, strategy);
  1219. }
  1220. };
  1221. template
  1222. <
  1223. typename Linestring, typename Polygon,
  1224. typename TupledOut,
  1225. overlay_type OverlayType,
  1226. bool ReverseLinestring, bool ReversePolygon
  1227. >
  1228. struct intersection_insert
  1229. <
  1230. Linestring, Polygon,
  1231. TupledOut,
  1232. OverlayType,
  1233. ReverseLinestring, ReversePolygon,
  1234. linestring_tag, polygon_tag, detail::tupled_output_tag,
  1235. linear_tag, areal_tag, detail::tupled_output_tag
  1236. > : detail::intersection::intersection_of_linestring_with_areal
  1237. <
  1238. ReversePolygon,
  1239. TupledOut,
  1240. OverlayType,
  1241. true
  1242. >
  1243. {};
  1244. template
  1245. <
  1246. typename Linestring, typename Ring,
  1247. typename TupledOut,
  1248. overlay_type OverlayType,
  1249. bool ReverseLinestring, bool ReverseRing
  1250. >
  1251. struct intersection_insert
  1252. <
  1253. Linestring, Ring,
  1254. TupledOut,
  1255. OverlayType,
  1256. ReverseLinestring, ReverseRing,
  1257. linestring_tag, ring_tag, detail::tupled_output_tag,
  1258. linear_tag, areal_tag, detail::tupled_output_tag
  1259. > : detail::intersection::intersection_of_linestring_with_areal
  1260. <
  1261. ReverseRing,
  1262. TupledOut,
  1263. OverlayType,
  1264. true
  1265. >
  1266. {};
  1267. } // namespace dispatch
  1268. #endif // DOXYGEN_NO_DISPATCH
  1269. #ifndef DOXYGEN_NO_DETAIL
  1270. namespace detail { namespace intersection
  1271. {
  1272. template
  1273. <
  1274. typename GeometryOut,
  1275. bool ReverseSecond,
  1276. overlay_type OverlayType,
  1277. typename Geometry1, typename Geometry2,
  1278. typename RobustPolicy,
  1279. typename OutputIterator,
  1280. typename Strategy
  1281. >
  1282. inline OutputIterator insert(Geometry1 const& geometry1,
  1283. Geometry2 const& geometry2,
  1284. RobustPolicy robust_policy,
  1285. OutputIterator out,
  1286. Strategy const& strategy)
  1287. {
  1288. return std::conditional_t
  1289. <
  1290. geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
  1291. geometry::dispatch::intersection_insert_reversed
  1292. <
  1293. Geometry1, Geometry2,
  1294. GeometryOut,
  1295. OverlayType,
  1296. overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
  1297. overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
  1298. >,
  1299. geometry::dispatch::intersection_insert
  1300. <
  1301. Geometry1, Geometry2,
  1302. GeometryOut,
  1303. OverlayType,
  1304. geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
  1305. geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
  1306. >
  1307. >::apply(geometry1, geometry2, robust_policy, out, strategy);
  1308. }
  1309. /*!
  1310. \brief \brief_calc2{intersection} \brief_strategy
  1311. \ingroup intersection
  1312. \details \details_calc2{intersection_insert, spatial set theoretic intersection}
  1313. \brief_strategy. \details_insert{intersection}
  1314. \tparam GeometryOut \tparam_geometry{\p_l_or_c}
  1315. \tparam Geometry1 \tparam_geometry
  1316. \tparam Geometry2 \tparam_geometry
  1317. \tparam OutputIterator \tparam_out{\p_l_or_c}
  1318. \tparam Strategy \tparam_strategy_overlay
  1319. \param geometry1 \param_geometry
  1320. \param geometry2 \param_geometry
  1321. \param out \param_out{intersection}
  1322. \param strategy \param_strategy{intersection}
  1323. \return \return_out
  1324. \qbk{distinguish,with strategy}
  1325. \qbk{[include reference/algorithms/intersection.qbk]}
  1326. */
  1327. template
  1328. <
  1329. typename GeometryOut,
  1330. typename Geometry1,
  1331. typename Geometry2,
  1332. typename OutputIterator,
  1333. typename Strategy
  1334. >
  1335. inline OutputIterator intersection_insert(Geometry1 const& geometry1,
  1336. Geometry2 const& geometry2,
  1337. OutputIterator out,
  1338. Strategy const& strategy)
  1339. {
  1340. concepts::check<Geometry1 const>();
  1341. concepts::check<Geometry2 const>();
  1342. typedef typename geometry::rescale_overlay_policy_type
  1343. <
  1344. Geometry1,
  1345. Geometry2,
  1346. typename Strategy::cs_tag
  1347. >::type rescale_policy_type;
  1348. rescale_policy_type robust_policy
  1349. = geometry::get_rescale_policy<rescale_policy_type>(
  1350. geometry1, geometry2, strategy);
  1351. return detail::intersection::insert
  1352. <
  1353. GeometryOut, false, overlay_intersection
  1354. >(geometry1, geometry2, robust_policy, out, strategy);
  1355. }
  1356. /*!
  1357. \brief \brief_calc2{intersection}
  1358. \ingroup intersection
  1359. \details \details_calc2{intersection_insert, spatial set theoretic intersection}.
  1360. \details_insert{intersection}
  1361. \tparam GeometryOut \tparam_geometry{\p_l_or_c}
  1362. \tparam Geometry1 \tparam_geometry
  1363. \tparam Geometry2 \tparam_geometry
  1364. \tparam OutputIterator \tparam_out{\p_l_or_c}
  1365. \param geometry1 \param_geometry
  1366. \param geometry2 \param_geometry
  1367. \param out \param_out{intersection}
  1368. \return \return_out
  1369. \qbk{[include reference/algorithms/intersection.qbk]}
  1370. */
  1371. template
  1372. <
  1373. typename GeometryOut,
  1374. typename Geometry1,
  1375. typename Geometry2,
  1376. typename OutputIterator
  1377. >
  1378. inline OutputIterator intersection_insert(Geometry1 const& geometry1,
  1379. Geometry2 const& geometry2,
  1380. OutputIterator out)
  1381. {
  1382. concepts::check<Geometry1 const>();
  1383. concepts::check<Geometry2 const>();
  1384. typedef typename strategies::relate::services::default_strategy
  1385. <
  1386. Geometry1, Geometry2
  1387. >::type strategy_type;
  1388. return intersection_insert<GeometryOut>(geometry1, geometry2, out,
  1389. strategy_type());
  1390. }
  1391. }} // namespace detail::intersection
  1392. #endif // DOXYGEN_NO_DETAIL
  1393. }} // namespace boost::geometry
  1394. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP