multi.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  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, 2020.
  4. // Modifications copyright (c) 2014-2020, 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 <boost/geometry/core/closure.hpp>
  12. #include <boost/geometry/core/geometry_id.hpp>
  13. #include <boost/geometry/core/is_areal.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. // TODO: those headers probably may be removed
  18. #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
  19. #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
  20. #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
  21. #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
  22. #include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
  23. #include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
  24. #include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
  25. #include <boost/geometry/algorithms/detail/intersection/interface.hpp>
  26. #include <boost/geometry/algorithms/covered_by.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 (typename boost::range_iterator
  52. <
  53. MultiLinestring1 const
  54. >::type it1 = boost::begin(ml1);
  55. it1 != boost::end(ml1);
  56. ++it1)
  57. {
  58. for (typename boost::range_iterator
  59. <
  60. MultiLinestring2 const
  61. >::type it2 = boost::begin(ml2);
  62. it2 != boost::end(ml2);
  63. ++it2)
  64. {
  65. out = intersection_linestring_linestring_point<PointOut>
  66. ::apply(*it1, *it2, robust_policy, out, strategy);
  67. }
  68. }
  69. return out;
  70. }
  71. };
  72. template <typename PointOut>
  73. struct intersection_linestring_multi_linestring_point
  74. {
  75. template
  76. <
  77. typename Linestring, typename MultiLinestring,
  78. typename RobustPolicy,
  79. typename OutputIterator, typename Strategy
  80. >
  81. static inline OutputIterator apply(Linestring const& linestring,
  82. MultiLinestring const& ml,
  83. RobustPolicy const& robust_policy,
  84. OutputIterator out,
  85. Strategy const& strategy)
  86. {
  87. for (typename boost::range_iterator
  88. <
  89. MultiLinestring const
  90. >::type it = boost::begin(ml);
  91. it != boost::end(ml);
  92. ++it)
  93. {
  94. out = intersection_linestring_linestring_point<PointOut>
  95. ::apply(linestring, *it, robust_policy, out, strategy);
  96. }
  97. return out;
  98. }
  99. };
  100. // This loop is quite similar to the loop above, but beacuse the iterator
  101. // is second (above) or first (below) argument, it is not trivial to merge them.
  102. template
  103. <
  104. bool ReverseAreal,
  105. typename LineStringOut,
  106. overlay_type OverlayType,
  107. bool FollowIsolatedPoints
  108. >
  109. struct intersection_of_multi_linestring_with_areal
  110. {
  111. template
  112. <
  113. typename MultiLinestring, typename Areal,
  114. typename RobustPolicy,
  115. typename OutputIterator, typename Strategy
  116. >
  117. static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
  118. RobustPolicy const& robust_policy,
  119. OutputIterator out,
  120. Strategy const& strategy)
  121. {
  122. for (typename boost::range_iterator
  123. <
  124. MultiLinestring const
  125. >::type it = boost::begin(ml);
  126. it != boost::end(ml);
  127. ++it)
  128. {
  129. out = intersection_of_linestring_with_areal
  130. <
  131. ReverseAreal, LineStringOut, OverlayType, FollowIsolatedPoints
  132. >::apply(*it, areal, robust_policy, out, strategy);
  133. }
  134. return out;
  135. }
  136. };
  137. // This one calls the one above with reversed arguments
  138. template
  139. <
  140. bool ReverseAreal,
  141. typename LineStringOut,
  142. overlay_type OverlayType,
  143. bool FollowIsolatedPoints
  144. >
  145. struct intersection_of_areal_with_multi_linestring
  146. {
  147. template
  148. <
  149. typename Areal, typename MultiLinestring,
  150. typename RobustPolicy,
  151. typename OutputIterator, typename Strategy
  152. >
  153. static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
  154. RobustPolicy const& robust_policy,
  155. OutputIterator out,
  156. Strategy const& strategy)
  157. {
  158. return intersection_of_multi_linestring_with_areal
  159. <
  160. ReverseAreal, LineStringOut, OverlayType, FollowIsolatedPoints
  161. >::apply(ml, areal, robust_policy, out, strategy);
  162. }
  163. };
  164. template <typename LinestringOut>
  165. struct clip_multi_linestring
  166. {
  167. template
  168. <
  169. typename MultiLinestring, typename Box,
  170. typename RobustPolicy,
  171. typename OutputIterator, typename Strategy
  172. >
  173. static inline OutputIterator apply(MultiLinestring const& multi_linestring,
  174. Box const& box,
  175. RobustPolicy const& robust_policy,
  176. OutputIterator out, Strategy const& )
  177. {
  178. typedef typename point_type<LinestringOut>::type point_type;
  179. strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
  180. for (typename boost::range_iterator<MultiLinestring const>::type it
  181. = boost::begin(multi_linestring);
  182. it != boost::end(multi_linestring); ++it)
  183. {
  184. out = detail::intersection::clip_range_with_box
  185. <LinestringOut>(box, *it, robust_policy, out, lb_strategy);
  186. }
  187. return out;
  188. }
  189. };
  190. }} // namespace detail::intersection
  191. #endif // DOXYGEN_NO_DETAIL
  192. #ifndef DOXYGEN_NO_DISPATCH
  193. namespace dispatch
  194. {
  195. // Linear
  196. template
  197. <
  198. typename MultiLinestring1, typename MultiLinestring2,
  199. typename GeometryOut,
  200. overlay_type OverlayType,
  201. bool Reverse1, bool Reverse2
  202. >
  203. struct intersection_insert
  204. <
  205. MultiLinestring1, MultiLinestring2,
  206. GeometryOut,
  207. OverlayType,
  208. Reverse1, Reverse2,
  209. multi_linestring_tag, multi_linestring_tag, point_tag,
  210. linear_tag, linear_tag, pointlike_tag
  211. > : detail::intersection::intersection_multi_linestring_multi_linestring_point
  212. <
  213. GeometryOut
  214. >
  215. {};
  216. template
  217. <
  218. typename Linestring, typename MultiLinestring,
  219. typename GeometryOut,
  220. overlay_type OverlayType,
  221. bool Reverse1, bool Reverse2
  222. >
  223. struct intersection_insert
  224. <
  225. Linestring, MultiLinestring,
  226. GeometryOut,
  227. OverlayType,
  228. Reverse1, Reverse2,
  229. linestring_tag, multi_linestring_tag, point_tag,
  230. linear_tag, linear_tag, pointlike_tag
  231. > : detail::intersection::intersection_linestring_multi_linestring_point
  232. <
  233. GeometryOut
  234. >
  235. {};
  236. template
  237. <
  238. typename MultiLinestring, typename Box,
  239. typename GeometryOut,
  240. overlay_type OverlayType,
  241. bool Reverse1, bool Reverse2
  242. >
  243. struct intersection_insert
  244. <
  245. MultiLinestring, Box,
  246. GeometryOut,
  247. OverlayType,
  248. Reverse1, Reverse2,
  249. multi_linestring_tag, box_tag, linestring_tag,
  250. linear_tag, areal_tag, linear_tag
  251. > : detail::intersection::clip_multi_linestring
  252. <
  253. GeometryOut
  254. >
  255. {};
  256. template
  257. <
  258. typename Linestring, typename MultiPolygon,
  259. typename GeometryOut,
  260. overlay_type OverlayType,
  261. bool ReverseLinestring, bool ReverseMultiPolygon
  262. >
  263. struct intersection_insert
  264. <
  265. Linestring, MultiPolygon,
  266. GeometryOut,
  267. OverlayType,
  268. ReverseLinestring, ReverseMultiPolygon,
  269. linestring_tag, multi_polygon_tag, linestring_tag,
  270. linear_tag, areal_tag, linear_tag
  271. > : detail::intersection::intersection_of_linestring_with_areal
  272. <
  273. ReverseMultiPolygon,
  274. GeometryOut,
  275. OverlayType,
  276. false
  277. >
  278. {};
  279. // Derives from areal/mls because runtime arguments are in that order.
  280. // areal/mls reverses it itself to mls/areal
  281. template
  282. <
  283. typename Polygon, typename MultiLinestring,
  284. typename GeometryOut,
  285. overlay_type OverlayType,
  286. bool ReversePolygon, bool ReverseMultiLinestring
  287. >
  288. struct intersection_insert
  289. <
  290. Polygon, MultiLinestring,
  291. GeometryOut,
  292. OverlayType,
  293. ReversePolygon, ReverseMultiLinestring,
  294. polygon_tag, multi_linestring_tag, linestring_tag,
  295. areal_tag, linear_tag, linear_tag
  296. > : detail::intersection::intersection_of_areal_with_multi_linestring
  297. <
  298. ReversePolygon,
  299. GeometryOut,
  300. OverlayType,
  301. false
  302. >
  303. {};
  304. template
  305. <
  306. typename MultiLinestring, typename Ring,
  307. typename GeometryOut,
  308. overlay_type OverlayType,
  309. bool ReverseMultiLinestring, bool ReverseRing
  310. >
  311. struct intersection_insert
  312. <
  313. MultiLinestring, Ring,
  314. GeometryOut,
  315. OverlayType,
  316. ReverseMultiLinestring, ReverseRing,
  317. multi_linestring_tag, ring_tag, linestring_tag,
  318. linear_tag, areal_tag, linear_tag
  319. > : detail::intersection::intersection_of_multi_linestring_with_areal
  320. <
  321. ReverseRing,
  322. GeometryOut,
  323. OverlayType,
  324. false
  325. >
  326. {};
  327. template
  328. <
  329. typename MultiLinestring, typename Polygon,
  330. typename GeometryOut,
  331. overlay_type OverlayType,
  332. bool ReverseMultiLinestring, bool ReversePolygon
  333. >
  334. struct intersection_insert
  335. <
  336. MultiLinestring, Polygon,
  337. GeometryOut,
  338. OverlayType,
  339. ReverseMultiLinestring, ReversePolygon,
  340. multi_linestring_tag, polygon_tag, linestring_tag,
  341. linear_tag, areal_tag, linear_tag
  342. > : detail::intersection::intersection_of_multi_linestring_with_areal
  343. <
  344. ReversePolygon,
  345. GeometryOut,
  346. OverlayType,
  347. false
  348. >
  349. {};
  350. template
  351. <
  352. typename MultiLinestring, typename MultiPolygon,
  353. typename GeometryOut,
  354. overlay_type OverlayType,
  355. bool ReverseMultiLinestring, bool ReverseMultiPolygon
  356. >
  357. struct intersection_insert
  358. <
  359. MultiLinestring, MultiPolygon,
  360. GeometryOut,
  361. OverlayType,
  362. ReverseMultiLinestring, ReverseMultiPolygon,
  363. multi_linestring_tag, multi_polygon_tag, linestring_tag,
  364. linear_tag, areal_tag, linear_tag
  365. > : detail::intersection::intersection_of_multi_linestring_with_areal
  366. <
  367. ReverseMultiPolygon,
  368. GeometryOut,
  369. OverlayType,
  370. false
  371. >
  372. {};
  373. template
  374. <
  375. typename MultiLinestring, typename Ring,
  376. typename TupledOut,
  377. overlay_type OverlayType,
  378. bool ReverseMultiLinestring, bool ReverseRing
  379. >
  380. struct intersection_insert
  381. <
  382. MultiLinestring, Ring,
  383. TupledOut,
  384. OverlayType,
  385. ReverseMultiLinestring, ReverseRing,
  386. multi_linestring_tag, ring_tag, detail::intersection::tupled_output_tag,
  387. linear_tag, areal_tag, detail::intersection::tupled_output_tag
  388. > : detail::intersection::intersection_of_multi_linestring_with_areal
  389. <
  390. ReverseRing,
  391. TupledOut,
  392. OverlayType,
  393. true
  394. >
  395. , detail::intersection::expect_output_pl<MultiLinestring, Ring, TupledOut>
  396. {};
  397. template
  398. <
  399. typename MultiLinestring, typename Polygon,
  400. typename TupledOut,
  401. overlay_type OverlayType,
  402. bool ReverseMultiLinestring, bool ReversePolygon
  403. >
  404. struct intersection_insert
  405. <
  406. MultiLinestring, Polygon,
  407. TupledOut,
  408. OverlayType,
  409. ReverseMultiLinestring, ReversePolygon,
  410. multi_linestring_tag, polygon_tag, detail::intersection::tupled_output_tag,
  411. linear_tag, areal_tag, detail::intersection::tupled_output_tag
  412. > : detail::intersection::intersection_of_multi_linestring_with_areal
  413. <
  414. ReversePolygon,
  415. TupledOut,
  416. OverlayType,
  417. true
  418. >
  419. , detail::intersection::expect_output_pl<MultiLinestring, Polygon, TupledOut>
  420. {};
  421. template
  422. <
  423. typename Polygon, typename MultiLinestring,
  424. typename TupledOut,
  425. overlay_type OverlayType,
  426. bool ReversePolygon, bool ReverseMultiLinestring
  427. >
  428. struct intersection_insert
  429. <
  430. Polygon, MultiLinestring,
  431. TupledOut,
  432. OverlayType,
  433. ReversePolygon, ReverseMultiLinestring,
  434. polygon_tag, multi_linestring_tag, detail::intersection::tupled_output_tag,
  435. areal_tag, linear_tag, detail::intersection::tupled_output_tag
  436. > : detail::intersection::intersection_of_areal_with_multi_linestring
  437. <
  438. ReversePolygon,
  439. TupledOut,
  440. OverlayType,
  441. true
  442. >
  443. , detail::intersection::expect_output_pl<Polygon, MultiLinestring, TupledOut>
  444. {};
  445. template
  446. <
  447. typename MultiLinestring, typename MultiPolygon,
  448. typename TupledOut,
  449. overlay_type OverlayType,
  450. bool ReverseMultiLinestring, bool ReverseMultiPolygon
  451. >
  452. struct intersection_insert
  453. <
  454. MultiLinestring, MultiPolygon,
  455. TupledOut,
  456. OverlayType,
  457. ReverseMultiLinestring, ReverseMultiPolygon,
  458. multi_linestring_tag, multi_polygon_tag, detail::intersection::tupled_output_tag,
  459. linear_tag, areal_tag, detail::intersection::tupled_output_tag
  460. > : detail::intersection::intersection_of_multi_linestring_with_areal
  461. <
  462. ReverseMultiPolygon,
  463. TupledOut,
  464. OverlayType,
  465. true
  466. >
  467. , detail::intersection::expect_output_pl<MultiLinestring, MultiPolygon, TupledOut>
  468. {};
  469. } // namespace dispatch
  470. #endif
  471. }} // namespace boost::geometry
  472. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP