multi.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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.
  4. // Modifications copyright (c) 2014-2015, 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. >
  108. struct intersection_of_multi_linestring_with_areal
  109. {
  110. template
  111. <
  112. typename MultiLinestring, typename Areal,
  113. typename RobustPolicy,
  114. typename OutputIterator, typename Strategy
  115. >
  116. static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
  117. RobustPolicy const& robust_policy,
  118. OutputIterator out,
  119. Strategy const& strategy)
  120. {
  121. for (typename boost::range_iterator
  122. <
  123. MultiLinestring const
  124. >::type it = boost::begin(ml);
  125. it != boost::end(ml);
  126. ++it)
  127. {
  128. out = intersection_of_linestring_with_areal
  129. <
  130. ReverseAreal, LineStringOut, OverlayType
  131. >::apply(*it, areal, robust_policy, out, strategy);
  132. }
  133. return out;
  134. }
  135. };
  136. // This one calls the one above with reversed arguments
  137. template
  138. <
  139. bool ReverseAreal,
  140. typename LineStringOut,
  141. overlay_type OverlayType
  142. >
  143. struct intersection_of_areal_with_multi_linestring
  144. {
  145. template
  146. <
  147. typename Areal, typename MultiLinestring,
  148. typename RobustPolicy,
  149. typename OutputIterator, typename Strategy
  150. >
  151. static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
  152. RobustPolicy const& robust_policy,
  153. OutputIterator out,
  154. Strategy const& strategy)
  155. {
  156. return intersection_of_multi_linestring_with_areal
  157. <
  158. ReverseAreal, LineStringOut, OverlayType
  159. >::apply(ml, areal, robust_policy, out, strategy);
  160. }
  161. };
  162. template <typename LinestringOut>
  163. struct clip_multi_linestring
  164. {
  165. template
  166. <
  167. typename MultiLinestring, typename Box,
  168. typename RobustPolicy,
  169. typename OutputIterator, typename Strategy
  170. >
  171. static inline OutputIterator apply(MultiLinestring const& multi_linestring,
  172. Box const& box,
  173. RobustPolicy const& robust_policy,
  174. OutputIterator out, Strategy const& )
  175. {
  176. typedef typename point_type<LinestringOut>::type point_type;
  177. strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
  178. for (typename boost::range_iterator<MultiLinestring const>::type it
  179. = boost::begin(multi_linestring);
  180. it != boost::end(multi_linestring); ++it)
  181. {
  182. out = detail::intersection::clip_range_with_box
  183. <LinestringOut>(box, *it, robust_policy, out, lb_strategy);
  184. }
  185. return out;
  186. }
  187. };
  188. }} // namespace detail::intersection
  189. #endif // DOXYGEN_NO_DETAIL
  190. #ifndef DOXYGEN_NO_DISPATCH
  191. namespace dispatch
  192. {
  193. // Linear
  194. template
  195. <
  196. typename MultiLinestring1, typename MultiLinestring2,
  197. typename GeometryOut,
  198. overlay_type OverlayType,
  199. bool Reverse1, bool Reverse2, bool ReverseOut
  200. >
  201. struct intersection_insert
  202. <
  203. MultiLinestring1, MultiLinestring2,
  204. GeometryOut,
  205. OverlayType,
  206. Reverse1, Reverse2, ReverseOut,
  207. multi_linestring_tag, multi_linestring_tag, point_tag,
  208. linear_tag, linear_tag, pointlike_tag
  209. > : detail::intersection::intersection_multi_linestring_multi_linestring_point
  210. <
  211. GeometryOut
  212. >
  213. {};
  214. template
  215. <
  216. typename Linestring, typename MultiLinestring,
  217. typename GeometryOut,
  218. overlay_type OverlayType,
  219. bool Reverse1, bool Reverse2, bool ReverseOut
  220. >
  221. struct intersection_insert
  222. <
  223. Linestring, MultiLinestring,
  224. GeometryOut,
  225. OverlayType,
  226. Reverse1, Reverse2, ReverseOut,
  227. linestring_tag, multi_linestring_tag, point_tag,
  228. linear_tag, linear_tag, pointlike_tag
  229. > : detail::intersection::intersection_linestring_multi_linestring_point
  230. <
  231. GeometryOut
  232. >
  233. {};
  234. template
  235. <
  236. typename MultiLinestring, typename Box,
  237. typename GeometryOut,
  238. overlay_type OverlayType,
  239. bool Reverse1, bool Reverse2, bool ReverseOut
  240. >
  241. struct intersection_insert
  242. <
  243. MultiLinestring, Box,
  244. GeometryOut,
  245. OverlayType,
  246. Reverse1, Reverse2, ReverseOut,
  247. multi_linestring_tag, box_tag, linestring_tag,
  248. linear_tag, areal_tag, linear_tag
  249. > : detail::intersection::clip_multi_linestring
  250. <
  251. GeometryOut
  252. >
  253. {};
  254. template
  255. <
  256. typename Linestring, typename MultiPolygon,
  257. typename GeometryOut,
  258. overlay_type OverlayType,
  259. bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut
  260. >
  261. struct intersection_insert
  262. <
  263. Linestring, MultiPolygon,
  264. GeometryOut,
  265. OverlayType,
  266. ReverseLinestring, ReverseMultiPolygon, ReverseOut,
  267. linestring_tag, multi_polygon_tag, linestring_tag,
  268. linear_tag, areal_tag, linear_tag
  269. > : detail::intersection::intersection_of_linestring_with_areal
  270. <
  271. ReverseMultiPolygon,
  272. GeometryOut,
  273. OverlayType
  274. >
  275. {};
  276. // Derives from areal/mls because runtime arguments are in that order.
  277. // areal/mls reverses it itself to mls/areal
  278. template
  279. <
  280. typename Polygon, typename MultiLinestring,
  281. typename GeometryOut,
  282. overlay_type OverlayType,
  283. bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut
  284. >
  285. struct intersection_insert
  286. <
  287. Polygon, MultiLinestring,
  288. GeometryOut,
  289. OverlayType,
  290. ReversePolygon, ReverseMultiLinestring, ReverseOut,
  291. polygon_tag, multi_linestring_tag, linestring_tag,
  292. areal_tag, linear_tag, linear_tag
  293. > : detail::intersection::intersection_of_areal_with_multi_linestring
  294. <
  295. ReversePolygon,
  296. GeometryOut,
  297. OverlayType
  298. >
  299. {};
  300. template
  301. <
  302. typename MultiLinestring, typename Ring,
  303. typename GeometryOut,
  304. overlay_type OverlayType,
  305. bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
  306. >
  307. struct intersection_insert
  308. <
  309. MultiLinestring, Ring,
  310. GeometryOut,
  311. OverlayType,
  312. ReverseMultiLinestring, ReverseRing, ReverseOut,
  313. multi_linestring_tag, ring_tag, linestring_tag,
  314. linear_tag, areal_tag, linear_tag
  315. > : detail::intersection::intersection_of_multi_linestring_with_areal
  316. <
  317. ReverseRing,
  318. GeometryOut,
  319. OverlayType
  320. >
  321. {};
  322. template
  323. <
  324. typename MultiLinestring, typename Polygon,
  325. typename GeometryOut,
  326. overlay_type OverlayType,
  327. bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
  328. >
  329. struct intersection_insert
  330. <
  331. MultiLinestring, Polygon,
  332. GeometryOut,
  333. OverlayType,
  334. ReverseMultiLinestring, ReverseRing, ReverseOut,
  335. multi_linestring_tag, polygon_tag, linestring_tag,
  336. linear_tag, areal_tag, linear_tag
  337. > : detail::intersection::intersection_of_multi_linestring_with_areal
  338. <
  339. ReverseRing,
  340. GeometryOut,
  341. OverlayType
  342. >
  343. {};
  344. template
  345. <
  346. typename MultiLinestring, typename MultiPolygon,
  347. typename GeometryOut,
  348. overlay_type OverlayType,
  349. bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut
  350. >
  351. struct intersection_insert
  352. <
  353. MultiLinestring, MultiPolygon,
  354. GeometryOut,
  355. OverlayType,
  356. ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
  357. multi_linestring_tag, multi_polygon_tag, linestring_tag,
  358. linear_tag, areal_tag, linear_tag
  359. > : detail::intersection::intersection_of_multi_linestring_with_areal
  360. <
  361. ReverseMultiPolygon,
  362. GeometryOut,
  363. OverlayType
  364. >
  365. {};
  366. } // namespace dispatch
  367. #endif
  368. }} // namespace boost::geometry
  369. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_MULTI_HPP