multi.hpp 17 KB

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