intersection.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Use, modification and distribution is subject to the Boost Software License,
  4. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
  7. #define BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
  8. #include <boost/geometry/multi/core/closure.hpp>
  9. #include <boost/geometry/multi/core/geometry_id.hpp>
  10. #include <boost/geometry/multi/core/is_areal.hpp>
  11. #include <boost/geometry/multi/core/point_order.hpp>
  12. #include <boost/geometry/multi/core/tags.hpp>
  13. #include <boost/geometry/multi/geometries/concepts/check.hpp>
  14. #include <boost/geometry/multi/algorithms/covered_by.hpp>
  15. #include <boost/geometry/multi/algorithms/envelope.hpp>
  16. #include <boost/geometry/multi/algorithms/num_points.hpp>
  17. #include <boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp>
  18. #include <boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp>
  19. #include <boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp>
  20. #include <boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp>
  21. #include <boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp>
  22. #include <boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp>
  23. #include <boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp>
  24. #include <boost/geometry/algorithms/intersection.hpp>
  25. namespace boost { namespace geometry
  26. {
  27. #ifndef DOXYGEN_NO_DETAIL
  28. namespace detail { namespace intersection
  29. {
  30. template <typename PointOut>
  31. struct intersection_multi_linestring_multi_linestring_point
  32. {
  33. template
  34. <
  35. typename MultiLinestring1, typename MultiLinestring2,
  36. typename OutputIterator, typename Strategy
  37. >
  38. static inline OutputIterator apply(MultiLinestring1 const& ml1,
  39. MultiLinestring2 const& ml2, OutputIterator out,
  40. Strategy const& strategy)
  41. {
  42. // Note, this loop is quadratic w.r.t. number of linestrings per input.
  43. // Future Enhancement: first do the sections of each, then intersect.
  44. for (typename boost::range_iterator
  45. <
  46. MultiLinestring1 const
  47. >::type it1 = boost::begin(ml1);
  48. it1 != boost::end(ml1);
  49. ++it1)
  50. {
  51. for (typename boost::range_iterator
  52. <
  53. MultiLinestring2 const
  54. >::type it2 = boost::begin(ml2);
  55. it2 != boost::end(ml2);
  56. ++it2)
  57. {
  58. out = intersection_linestring_linestring_point<PointOut>
  59. ::apply(*it1, *it2, out, strategy);
  60. }
  61. }
  62. return out;
  63. }
  64. };
  65. template <typename PointOut>
  66. struct intersection_linestring_multi_linestring_point
  67. {
  68. template
  69. <
  70. typename Linestring, typename MultiLinestring,
  71. typename OutputIterator, typename Strategy
  72. >
  73. static inline OutputIterator apply(Linestring const& linestring,
  74. MultiLinestring const& ml, OutputIterator out,
  75. Strategy const& strategy)
  76. {
  77. for (typename boost::range_iterator
  78. <
  79. MultiLinestring const
  80. >::type it = boost::begin(ml);
  81. it != boost::end(ml);
  82. ++it)
  83. {
  84. out = intersection_linestring_linestring_point<PointOut>
  85. ::apply(linestring, *it, out, strategy);
  86. }
  87. return out;
  88. }
  89. };
  90. // This loop is quite similar to the loop above, but beacuse the iterator
  91. // is second (above) or first (below) argument, it is not trivial to merge them.
  92. template
  93. <
  94. bool ReverseAreal,
  95. typename LineStringOut,
  96. overlay_type OverlayType
  97. >
  98. struct intersection_of_multi_linestring_with_areal
  99. {
  100. template
  101. <
  102. typename MultiLinestring, typename Areal,
  103. typename OutputIterator, typename Strategy
  104. >
  105. static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
  106. OutputIterator out,
  107. Strategy const& strategy)
  108. {
  109. for (typename boost::range_iterator
  110. <
  111. MultiLinestring const
  112. >::type it = boost::begin(ml);
  113. it != boost::end(ml);
  114. ++it)
  115. {
  116. out = intersection_of_linestring_with_areal
  117. <
  118. ReverseAreal, LineStringOut, OverlayType
  119. >::apply(*it, areal, out, strategy);
  120. }
  121. return out;
  122. }
  123. };
  124. // This one calls the one above with reversed arguments
  125. template
  126. <
  127. bool ReverseAreal,
  128. typename LineStringOut,
  129. overlay_type OverlayType
  130. >
  131. struct intersection_of_areal_with_multi_linestring
  132. {
  133. template
  134. <
  135. typename Areal, typename MultiLinestring,
  136. typename OutputIterator, typename Strategy
  137. >
  138. static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
  139. OutputIterator out,
  140. Strategy const& strategy)
  141. {
  142. return intersection_of_multi_linestring_with_areal
  143. <
  144. ReverseAreal, LineStringOut, OverlayType
  145. >::apply(ml, areal, out, strategy);
  146. }
  147. };
  148. template <typename LinestringOut>
  149. struct clip_multi_linestring
  150. {
  151. template
  152. <
  153. typename MultiLinestring, typename Box,
  154. typename OutputIterator, typename Strategy
  155. >
  156. static inline OutputIterator apply(MultiLinestring const& multi_linestring,
  157. Box const& box, OutputIterator out, Strategy const& )
  158. {
  159. typedef typename point_type<LinestringOut>::type point_type;
  160. strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
  161. for (typename boost::range_iterator<MultiLinestring const>::type it
  162. = boost::begin(multi_linestring);
  163. it != boost::end(multi_linestring); ++it)
  164. {
  165. out = detail::intersection::clip_range_with_box
  166. <LinestringOut>(box, *it, out, lb_strategy);
  167. }
  168. return out;
  169. }
  170. };
  171. }} // namespace detail::intersection
  172. #endif // DOXYGEN_NO_DETAIL
  173. #ifndef DOXYGEN_NO_DISPATCH
  174. namespace dispatch
  175. {
  176. // Linear
  177. template
  178. <
  179. typename MultiLinestring1, typename MultiLinestring2,
  180. typename GeometryOut,
  181. overlay_type OverlayType,
  182. bool Reverse1, bool Reverse2, bool ReverseOut
  183. >
  184. struct intersection_insert
  185. <
  186. MultiLinestring1, MultiLinestring2,
  187. GeometryOut,
  188. OverlayType,
  189. Reverse1, Reverse2, ReverseOut,
  190. multi_linestring_tag, multi_linestring_tag, point_tag,
  191. false, false, false
  192. > : detail::intersection::intersection_multi_linestring_multi_linestring_point
  193. <
  194. GeometryOut
  195. >
  196. {};
  197. template
  198. <
  199. typename Linestring, typename MultiLinestring,
  200. typename GeometryOut,
  201. overlay_type OverlayType,
  202. bool Reverse1, bool Reverse2, bool ReverseOut
  203. >
  204. struct intersection_insert
  205. <
  206. Linestring, MultiLinestring,
  207. GeometryOut,
  208. OverlayType,
  209. Reverse1, Reverse2, ReverseOut,
  210. linestring_tag, multi_linestring_tag, point_tag,
  211. false, false, false
  212. > : detail::intersection::intersection_linestring_multi_linestring_point
  213. <
  214. GeometryOut
  215. >
  216. {};
  217. template
  218. <
  219. typename MultiLinestring, typename Box,
  220. typename GeometryOut,
  221. overlay_type OverlayType,
  222. bool Reverse1, bool Reverse2, bool ReverseOut
  223. >
  224. struct intersection_insert
  225. <
  226. MultiLinestring, Box,
  227. GeometryOut,
  228. OverlayType,
  229. Reverse1, Reverse2, ReverseOut,
  230. multi_linestring_tag, box_tag, linestring_tag,
  231. false, true, false
  232. > : detail::intersection::clip_multi_linestring
  233. <
  234. GeometryOut
  235. >
  236. {};
  237. template
  238. <
  239. typename Linestring, typename MultiPolygon,
  240. typename GeometryOut,
  241. overlay_type OverlayType,
  242. bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut
  243. >
  244. struct intersection_insert
  245. <
  246. Linestring, MultiPolygon,
  247. GeometryOut,
  248. OverlayType,
  249. ReverseLinestring, ReverseMultiPolygon, ReverseOut,
  250. linestring_tag, multi_polygon_tag, linestring_tag,
  251. false, true, false
  252. > : detail::intersection::intersection_of_linestring_with_areal
  253. <
  254. ReverseMultiPolygon,
  255. GeometryOut,
  256. OverlayType
  257. >
  258. {};
  259. // Derives from areal/mls because runtime arguments are in that order.
  260. // areal/mls reverses it itself to mls/areal
  261. template
  262. <
  263. typename Polygon, typename MultiLinestring,
  264. typename GeometryOut,
  265. overlay_type OverlayType,
  266. bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut
  267. >
  268. struct intersection_insert
  269. <
  270. Polygon, MultiLinestring,
  271. GeometryOut,
  272. OverlayType,
  273. ReversePolygon, ReverseMultiLinestring, ReverseOut,
  274. polygon_tag, multi_linestring_tag, linestring_tag,
  275. true, false, false
  276. > : detail::intersection::intersection_of_areal_with_multi_linestring
  277. <
  278. ReversePolygon,
  279. GeometryOut,
  280. OverlayType
  281. >
  282. {};
  283. template
  284. <
  285. typename MultiLinestring, typename Ring,
  286. typename GeometryOut,
  287. overlay_type OverlayType,
  288. bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
  289. >
  290. struct intersection_insert
  291. <
  292. MultiLinestring, Ring,
  293. GeometryOut,
  294. OverlayType,
  295. ReverseMultiLinestring, ReverseRing, ReverseOut,
  296. multi_linestring_tag, ring_tag, linestring_tag,
  297. false, true, false
  298. > : detail::intersection::intersection_of_multi_linestring_with_areal
  299. <
  300. ReverseRing,
  301. GeometryOut,
  302. OverlayType
  303. >
  304. {};
  305. template
  306. <
  307. typename MultiLinestring, typename Polygon,
  308. typename GeometryOut,
  309. overlay_type OverlayType,
  310. bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
  311. >
  312. struct intersection_insert
  313. <
  314. MultiLinestring, Polygon,
  315. GeometryOut,
  316. OverlayType,
  317. ReverseMultiLinestring, ReverseRing, ReverseOut,
  318. multi_linestring_tag, polygon_tag, linestring_tag,
  319. false, true, false
  320. > : detail::intersection::intersection_of_multi_linestring_with_areal
  321. <
  322. ReverseRing,
  323. GeometryOut,
  324. OverlayType
  325. >
  326. {};
  327. template
  328. <
  329. typename MultiLinestring, typename MultiPolygon,
  330. typename GeometryOut,
  331. overlay_type OverlayType,
  332. bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut
  333. >
  334. struct intersection_insert
  335. <
  336. MultiLinestring, MultiPolygon,
  337. GeometryOut,
  338. OverlayType,
  339. ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
  340. multi_linestring_tag, multi_polygon_tag, linestring_tag,
  341. false, true, false
  342. > : detail::intersection::intersection_of_multi_linestring_with_areal
  343. <
  344. ReverseMultiPolygon,
  345. GeometryOut,
  346. OverlayType
  347. >
  348. {};
  349. } // namespace dispatch
  350. #endif
  351. }} // namespace boost::geometry
  352. #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP