multi.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  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-2022.
  4. // Modifications copyright (c) 2014-2022, Oracle and/or its affiliates.
  5. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  6. // Use, modification and distribution is subject to the Boost Software License,
  7. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
  10. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP
  11. #include <type_traits>
  12. #include <boost/geometry/core/closure.hpp>
  13. #include <boost/geometry/core/geometry_id.hpp>
  14. #include <boost/geometry/core/point_order.hpp>
  15. #include <boost/geometry/core/tags.hpp>
  16. #include <boost/geometry/geometries/concepts/check.hpp>
  17. #include <boost/geometry/algorithms/detail/covered_by/implementation.hpp>
  18. // TODO: those headers probably may be removed
  19. #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
  20. #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
  21. #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
  22. #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
  23. #include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
  24. #include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
  25. #include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
  26. #include <boost/geometry/algorithms/detail/intersection/interface.hpp>
  27. #include <boost/geometry/algorithms/envelope.hpp>
  28. #include <boost/geometry/algorithms/num_points.hpp>
  29. namespace boost { namespace geometry
  30. {
  31. #ifndef DOXYGEN_NO_DETAIL
  32. namespace detail { namespace intersection
  33. {
  34. template <typename PointOut>
  35. struct intersection_multi_linestring_multi_linestring_point
  36. {
  37. template
  38. <
  39. typename MultiLinestring1, typename MultiLinestring2,
  40. typename RobustPolicy,
  41. typename OutputIterator, typename Strategy
  42. >
  43. static inline OutputIterator apply(MultiLinestring1 const& ml1,
  44. MultiLinestring2 const& ml2,
  45. RobustPolicy const& robust_policy,
  46. OutputIterator out,
  47. Strategy const& strategy)
  48. {
  49. // Note, this loop is quadratic w.r.t. number of linestrings per input.
  50. // Future Enhancement: first do the sections of each, then intersect.
  51. for (auto it1 = boost::begin(ml1); it1 != boost::end(ml1); ++it1)
  52. {
  53. for (auto it2 = boost::begin(ml2); it2 != boost::end(ml2); ++it2)
  54. {
  55. out = intersection_linestring_linestring_point<PointOut>
  56. ::apply(*it1, *it2, robust_policy, out, strategy);
  57. }
  58. }
  59. return out;
  60. }
  61. };
  62. template <typename PointOut>
  63. struct intersection_linestring_multi_linestring_point
  64. {
  65. template
  66. <
  67. typename Linestring, typename MultiLinestring,
  68. typename RobustPolicy,
  69. typename OutputIterator, typename Strategy
  70. >
  71. static inline OutputIterator apply(Linestring const& linestring,
  72. MultiLinestring const& ml,
  73. RobustPolicy const& robust_policy,
  74. OutputIterator out,
  75. Strategy const& strategy)
  76. {
  77. for (auto it = boost::begin(ml); it != boost::end(ml); ++it)
  78. {
  79. out = intersection_linestring_linestring_point<PointOut>
  80. ::apply(linestring, *it, robust_policy, out, strategy);
  81. }
  82. return out;
  83. }
  84. };
  85. // This loop is quite similar to the loop above, but beacuse the iterator
  86. // is second (above) or first (below) argument, it is not trivial to merge them.
  87. template
  88. <
  89. bool ReverseAreal,
  90. typename LineStringOut,
  91. overlay_type OverlayType,
  92. bool FollowIsolatedPoints
  93. >
  94. struct intersection_of_multi_linestring_with_areal
  95. {
  96. template
  97. <
  98. typename MultiLinestring, typename Areal,
  99. typename RobustPolicy,
  100. typename OutputIterator, typename Strategy
  101. >
  102. static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
  103. RobustPolicy const& robust_policy,
  104. OutputIterator out,
  105. Strategy const& strategy)
  106. {
  107. for (auto it = boost::begin(ml); it != boost::end(ml); ++it)
  108. {
  109. out = intersection_of_linestring_with_areal
  110. <
  111. ReverseAreal, LineStringOut, OverlayType, FollowIsolatedPoints
  112. >::apply(*it, areal, robust_policy, out, strategy);
  113. }
  114. return out;
  115. }
  116. };
  117. // This one calls the one above with reversed arguments
  118. template
  119. <
  120. bool ReverseAreal,
  121. typename LineStringOut,
  122. overlay_type OverlayType,
  123. bool FollowIsolatedPoints
  124. >
  125. struct intersection_of_areal_with_multi_linestring
  126. {
  127. template
  128. <
  129. typename Areal, typename MultiLinestring,
  130. typename RobustPolicy,
  131. typename OutputIterator, typename Strategy
  132. >
  133. static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
  134. RobustPolicy const& robust_policy,
  135. OutputIterator out,
  136. Strategy const& strategy)
  137. {
  138. return intersection_of_multi_linestring_with_areal
  139. <
  140. ReverseAreal, LineStringOut, OverlayType, FollowIsolatedPoints
  141. >::apply(ml, areal, robust_policy, out, strategy);
  142. }
  143. };
  144. template <typename LinestringOut>
  145. struct clip_multi_linestring
  146. {
  147. template
  148. <
  149. typename MultiLinestring, typename Box,
  150. typename RobustPolicy,
  151. typename OutputIterator, typename Strategy
  152. >
  153. static inline OutputIterator apply(MultiLinestring const& multi_linestring,
  154. Box const& box,
  155. RobustPolicy const& robust_policy,
  156. OutputIterator out, Strategy const& )
  157. {
  158. typedef typename point_type<LinestringOut>::type point_type;
  159. strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
  160. for (auto it = boost::begin(multi_linestring); it != boost::end(multi_linestring); ++it)
  161. {
  162. out = detail::intersection::clip_range_with_box
  163. <LinestringOut>(box, *it, robust_policy, out, lb_strategy);
  164. }
  165. return out;
  166. }
  167. };
  168. }} // namespace detail::intersection
  169. #endif // DOXYGEN_NO_DETAIL
  170. #ifndef DOXYGEN_NO_DISPATCH
  171. namespace dispatch
  172. {
  173. // Linear
  174. template
  175. <
  176. typename MultiLinestring1, typename MultiLinestring2,
  177. typename GeometryOut,
  178. overlay_type OverlayType,
  179. bool Reverse1, bool Reverse2
  180. >
  181. struct intersection_insert
  182. <
  183. MultiLinestring1, MultiLinestring2,
  184. GeometryOut,
  185. OverlayType,
  186. Reverse1, Reverse2,
  187. multi_linestring_tag, multi_linestring_tag, point_tag,
  188. linear_tag, linear_tag, pointlike_tag
  189. > : detail::intersection::intersection_multi_linestring_multi_linestring_point
  190. <
  191. GeometryOut
  192. >
  193. {};
  194. template
  195. <
  196. typename Linestring, typename MultiLinestring,
  197. typename GeometryOut,
  198. overlay_type OverlayType,
  199. bool Reverse1, bool Reverse2
  200. >
  201. struct intersection_insert
  202. <
  203. Linestring, MultiLinestring,
  204. GeometryOut,
  205. OverlayType,
  206. Reverse1, Reverse2,
  207. linestring_tag, multi_linestring_tag, point_tag,
  208. linear_tag, linear_tag, pointlike_tag
  209. > : detail::intersection::intersection_linestring_multi_linestring_point
  210. <
  211. GeometryOut
  212. >
  213. {};
  214. template
  215. <
  216. typename MultiLinestring, typename Box,
  217. typename GeometryOut,
  218. overlay_type OverlayType,
  219. bool Reverse1, bool Reverse2
  220. >
  221. struct intersection_insert
  222. <
  223. MultiLinestring, Box,
  224. GeometryOut,
  225. OverlayType,
  226. Reverse1, Reverse2,
  227. multi_linestring_tag, box_tag, linestring_tag,
  228. linear_tag, areal_tag, linear_tag
  229. > : detail::intersection::clip_multi_linestring
  230. <
  231. GeometryOut
  232. >
  233. {};
  234. template
  235. <
  236. typename Linestring, typename MultiPolygon,
  237. typename GeometryOut,
  238. overlay_type OverlayType,
  239. bool ReverseLinestring, bool ReverseMultiPolygon
  240. >
  241. struct intersection_insert
  242. <
  243. Linestring, MultiPolygon,
  244. GeometryOut,
  245. OverlayType,
  246. ReverseLinestring, ReverseMultiPolygon,
  247. linestring_tag, multi_polygon_tag, linestring_tag,
  248. linear_tag, areal_tag, linear_tag
  249. > : detail::intersection::intersection_of_linestring_with_areal
  250. <
  251. ReverseMultiPolygon,
  252. GeometryOut,
  253. OverlayType,
  254. false
  255. >
  256. {};
  257. // Derives from areal/mls because runtime arguments are in that order.
  258. // areal/mls reverses it itself to mls/areal
  259. template
  260. <
  261. typename Polygon, typename MultiLinestring,
  262. typename GeometryOut,
  263. overlay_type OverlayType,
  264. bool ReversePolygon, bool ReverseMultiLinestring
  265. >
  266. struct intersection_insert
  267. <
  268. Polygon, MultiLinestring,
  269. GeometryOut,
  270. OverlayType,
  271. ReversePolygon, ReverseMultiLinestring,
  272. polygon_tag, multi_linestring_tag, linestring_tag,
  273. areal_tag, linear_tag, linear_tag
  274. > : detail::intersection::intersection_of_areal_with_multi_linestring
  275. <
  276. ReversePolygon,
  277. GeometryOut,
  278. OverlayType,
  279. false
  280. >
  281. {};
  282. template
  283. <
  284. typename MultiLinestring, typename Ring,
  285. typename GeometryOut,
  286. overlay_type OverlayType,
  287. bool ReverseMultiLinestring, bool ReverseRing
  288. >
  289. struct intersection_insert
  290. <
  291. MultiLinestring, Ring,
  292. GeometryOut,
  293. OverlayType,
  294. ReverseMultiLinestring, ReverseRing,
  295. multi_linestring_tag, ring_tag, linestring_tag,
  296. linear_tag, areal_tag, linear_tag
  297. > : detail::intersection::intersection_of_multi_linestring_with_areal
  298. <
  299. ReverseRing,
  300. GeometryOut,
  301. OverlayType,
  302. false
  303. >
  304. {};
  305. template
  306. <
  307. typename MultiLinestring, typename Polygon,
  308. typename GeometryOut,
  309. overlay_type OverlayType,
  310. bool ReverseMultiLinestring, bool ReversePolygon
  311. >
  312. struct intersection_insert
  313. <
  314. MultiLinestring, Polygon,
  315. GeometryOut,
  316. OverlayType,
  317. ReverseMultiLinestring, ReversePolygon,
  318. multi_linestring_tag, polygon_tag, linestring_tag,
  319. linear_tag, areal_tag, linear_tag
  320. > : detail::intersection::intersection_of_multi_linestring_with_areal
  321. <
  322. ReversePolygon,
  323. GeometryOut,
  324. OverlayType,
  325. false
  326. >
  327. {};
  328. template
  329. <
  330. typename MultiLinestring, typename MultiPolygon,
  331. typename GeometryOut,
  332. overlay_type OverlayType,
  333. bool ReverseMultiLinestring, bool ReverseMultiPolygon
  334. >
  335. struct intersection_insert
  336. <
  337. MultiLinestring, MultiPolygon,
  338. GeometryOut,
  339. OverlayType,
  340. ReverseMultiLinestring, ReverseMultiPolygon,
  341. multi_linestring_tag, multi_polygon_tag, linestring_tag,
  342. linear_tag, areal_tag, linear_tag
  343. > : detail::intersection::intersection_of_multi_linestring_with_areal
  344. <
  345. ReverseMultiPolygon,
  346. GeometryOut,
  347. OverlayType,
  348. false
  349. >
  350. {};
  351. template
  352. <
  353. typename MultiLinestring, typename Ring,
  354. typename TupledOut,
  355. overlay_type OverlayType,
  356. bool ReverseMultiLinestring, bool ReverseRing
  357. >
  358. struct intersection_insert
  359. <
  360. MultiLinestring, Ring,
  361. TupledOut,
  362. OverlayType,
  363. ReverseMultiLinestring, ReverseRing,
  364. multi_linestring_tag, ring_tag, detail::tupled_output_tag,
  365. linear_tag, areal_tag, detail::tupled_output_tag
  366. > : detail::intersection::intersection_of_multi_linestring_with_areal
  367. <
  368. ReverseRing,
  369. TupledOut,
  370. OverlayType,
  371. true
  372. >
  373. , detail::expect_output
  374. <
  375. MultiLinestring, Ring, TupledOut,
  376. // NOTE: points can be the result only in case of intersection.
  377. // TODO: union should require L and A
  378. std::conditional_t
  379. <
  380. (OverlayType == overlay_intersection),
  381. point_tag,
  382. void
  383. >,
  384. linestring_tag
  385. >
  386. {};
  387. template
  388. <
  389. typename MultiLinestring, typename Polygon,
  390. typename TupledOut,
  391. overlay_type OverlayType,
  392. bool ReverseMultiLinestring, bool ReversePolygon
  393. >
  394. struct intersection_insert
  395. <
  396. MultiLinestring, Polygon,
  397. TupledOut,
  398. OverlayType,
  399. ReverseMultiLinestring, ReversePolygon,
  400. multi_linestring_tag, polygon_tag, detail::tupled_output_tag,
  401. linear_tag, areal_tag, detail::tupled_output_tag
  402. > : detail::intersection::intersection_of_multi_linestring_with_areal
  403. <
  404. ReversePolygon,
  405. TupledOut,
  406. OverlayType,
  407. true
  408. >
  409. , detail::expect_output
  410. <
  411. MultiLinestring, Polygon, TupledOut,
  412. // NOTE: points can be the result only in case of intersection.
  413. // TODO: union should require L and A
  414. std::conditional_t
  415. <
  416. (OverlayType == overlay_intersection),
  417. point_tag,
  418. void
  419. >,
  420. linestring_tag
  421. >
  422. {};
  423. template
  424. <
  425. typename Polygon, typename MultiLinestring,
  426. typename TupledOut,
  427. overlay_type OverlayType,
  428. bool ReversePolygon, bool ReverseMultiLinestring
  429. >
  430. struct intersection_insert
  431. <
  432. Polygon, MultiLinestring,
  433. TupledOut,
  434. OverlayType,
  435. ReversePolygon, ReverseMultiLinestring,
  436. polygon_tag, multi_linestring_tag, detail::tupled_output_tag,
  437. areal_tag, linear_tag, detail::tupled_output_tag
  438. > : detail::intersection::intersection_of_areal_with_multi_linestring
  439. <
  440. ReversePolygon,
  441. TupledOut,
  442. OverlayType,
  443. true
  444. >
  445. , detail::expect_output
  446. <
  447. Polygon, MultiLinestring, TupledOut,
  448. // NOTE: points can be the result only in case of intersection.
  449. // TODO: union should require L and A
  450. // TODO: in general the result of difference should depend on the first argument
  451. // but this specialization calls L/A in reality so the first argument is linear.
  452. // So expect only L for difference?
  453. std::conditional_t
  454. <
  455. (OverlayType == overlay_intersection),
  456. point_tag,
  457. void
  458. >,
  459. linestring_tag
  460. >
  461. {};
  462. template
  463. <
  464. typename Linestring, typename MultiPolygon,
  465. typename TupledOut,
  466. overlay_type OverlayType,
  467. bool ReverseMultiLinestring, bool ReverseMultiPolygon
  468. >
  469. struct intersection_insert
  470. <
  471. Linestring, MultiPolygon,
  472. TupledOut,
  473. OverlayType,
  474. ReverseMultiLinestring, ReverseMultiPolygon,
  475. linestring_tag, multi_polygon_tag, detail::tupled_output_tag,
  476. linear_tag, areal_tag, detail::tupled_output_tag
  477. > : detail::intersection::intersection_of_linestring_with_areal
  478. <
  479. ReverseMultiPolygon, TupledOut, OverlayType, true
  480. >
  481. , detail::expect_output
  482. <
  483. Linestring, MultiPolygon, TupledOut,
  484. // NOTE: points can be the result only in case of intersection.
  485. // TODO: union should require L and A
  486. std::conditional_t
  487. <
  488. (OverlayType == overlay_intersection),
  489. point_tag,
  490. void
  491. >,
  492. linestring_tag
  493. >
  494. {};
  495. template
  496. <
  497. typename MultiLinestring, typename MultiPolygon,
  498. typename TupledOut,
  499. overlay_type OverlayType,
  500. bool ReverseMultiLinestring, bool ReverseMultiPolygon
  501. >
  502. struct intersection_insert
  503. <
  504. MultiLinestring, MultiPolygon,
  505. TupledOut,
  506. OverlayType,
  507. ReverseMultiLinestring, ReverseMultiPolygon,
  508. multi_linestring_tag, multi_polygon_tag, detail::tupled_output_tag,
  509. linear_tag, areal_tag, detail::tupled_output_tag
  510. > : detail::intersection::intersection_of_multi_linestring_with_areal
  511. <
  512. ReverseMultiPolygon,
  513. TupledOut,
  514. OverlayType,
  515. true
  516. >
  517. , detail::expect_output
  518. <
  519. MultiLinestring, MultiPolygon, TupledOut,
  520. // NOTE: points can be the result only in case of intersection.
  521. // TODO: union should require L and A
  522. std::conditional_t
  523. <
  524. (OverlayType == overlay_intersection),
  525. point_tag,
  526. void
  527. >,
  528. linestring_tag
  529. >
  530. {};
  531. } // namespace dispatch
  532. #endif
  533. }} // namespace boost::geometry
  534. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP