linear_linear.hpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2014-2019, Oracle and/or its affiliates.
  3. // Licensed under the Boost Software License version 1.0.
  4. // http://www.boost.org/users/license.html
  5. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  6. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  7. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_LINEAR_LINEAR_HPP
  8. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_LINEAR_LINEAR_HPP
  9. #include <algorithm>
  10. #include <vector>
  11. #include <boost/range.hpp>
  12. #include <boost/geometry/core/tag.hpp>
  13. #include <boost/geometry/core/tags.hpp>
  14. #include <boost/geometry/algorithms/detail/relate/turns.hpp>
  15. #include <boost/geometry/algorithms/detail/turns/compare_turns.hpp>
  16. #include <boost/geometry/algorithms/detail/turns/filter_continue_turns.hpp>
  17. #include <boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp>
  18. #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
  19. #include <boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp>
  20. #include <boost/geometry/algorithms/convert.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. #ifndef DOXYGEN_NO_DETAIL
  24. namespace detail { namespace overlay
  25. {
  26. template
  27. <
  28. typename LineStringOut,
  29. overlay_type OverlayType,
  30. typename Geometry,
  31. typename GeometryTag
  32. >
  33. struct linear_linear_no_intersections;
  34. template <typename LineStringOut, typename LineString>
  35. struct linear_linear_no_intersections
  36. <
  37. LineStringOut, overlay_difference, LineString, linestring_tag
  38. >
  39. {
  40. template <typename OutputIterator>
  41. static inline OutputIterator apply(LineString const& linestring,
  42. OutputIterator oit)
  43. {
  44. LineStringOut ls_out;
  45. geometry::convert(linestring, ls_out);
  46. *oit++ = ls_out;
  47. return oit;
  48. }
  49. };
  50. template <typename LineStringOut, typename MultiLineString>
  51. struct linear_linear_no_intersections
  52. <
  53. LineStringOut,
  54. overlay_difference,
  55. MultiLineString,
  56. multi_linestring_tag
  57. >
  58. {
  59. template <typename OutputIterator>
  60. static inline OutputIterator apply(MultiLineString const& multilinestring,
  61. OutputIterator oit)
  62. {
  63. for (typename boost::range_iterator<MultiLineString const>::type
  64. it = boost::begin(multilinestring);
  65. it != boost::end(multilinestring); ++it)
  66. {
  67. LineStringOut ls_out;
  68. geometry::convert(*it, ls_out);
  69. *oit++ = ls_out;
  70. }
  71. return oit;
  72. }
  73. };
  74. template <typename LineStringOut, typename Geometry, typename GeometryTag>
  75. struct linear_linear_no_intersections
  76. <
  77. LineStringOut, overlay_intersection, Geometry, GeometryTag
  78. >
  79. {
  80. template <typename OutputIterator>
  81. static inline OutputIterator apply(Geometry const&,
  82. OutputIterator oit)
  83. {
  84. return oit;
  85. }
  86. };
  87. template
  88. <
  89. typename Linear1,
  90. typename Linear2,
  91. typename LinestringOut,
  92. overlay_type OverlayType,
  93. bool EnableFilterContinueTurns = false,
  94. bool EnableRemoveDuplicateTurns = false,
  95. bool EnableDegenerateTurns = true,
  96. #ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS
  97. bool EnableFollowIsolatedPoints = false
  98. #else
  99. bool EnableFollowIsolatedPoints = true
  100. #endif
  101. >
  102. class linear_linear_linestring
  103. {
  104. protected:
  105. struct assign_policy
  106. {
  107. static bool const include_no_turn = false;
  108. static bool const include_degenerate = EnableDegenerateTurns;
  109. static bool const include_opposite = false;
  110. };
  111. template
  112. <
  113. typename Turns,
  114. typename LinearGeometry1,
  115. typename LinearGeometry2,
  116. typename IntersectionStrategy,
  117. typename RobustPolicy
  118. >
  119. static inline void compute_turns(Turns& turns,
  120. LinearGeometry1 const& linear1,
  121. LinearGeometry2 const& linear2,
  122. IntersectionStrategy const& strategy,
  123. RobustPolicy const& robust_policy)
  124. {
  125. turns.clear();
  126. detail::get_turns::no_interrupt_policy interrupt_policy;
  127. geometry::detail::relate::turns::get_turns
  128. <
  129. LinearGeometry1,
  130. LinearGeometry2,
  131. detail::get_turns::get_turn_info_type
  132. <
  133. LinearGeometry1,
  134. LinearGeometry2,
  135. assign_policy
  136. >
  137. >::apply(turns, linear1, linear2, interrupt_policy, strategy, robust_policy);
  138. }
  139. template
  140. <
  141. overlay_type OverlayTypeForFollow,
  142. bool FollowIsolatedPoints,
  143. typename Turns,
  144. typename LinearGeometry1,
  145. typename LinearGeometry2,
  146. typename OutputIterator,
  147. typename IntersectionStrategy
  148. >
  149. static inline OutputIterator
  150. sort_and_follow_turns(Turns& turns,
  151. LinearGeometry1 const& linear1,
  152. LinearGeometry2 const& linear2,
  153. OutputIterator oit,
  154. IntersectionStrategy const& strategy)
  155. {
  156. // remove turns that have no added value
  157. turns::filter_continue_turns
  158. <
  159. Turns,
  160. EnableFilterContinueTurns && OverlayType != overlay_intersection
  161. >::apply(turns);
  162. // sort by seg_id, distance, and operation
  163. std::sort(boost::begin(turns), boost::end(turns),
  164. detail::turns::less_seg_fraction_other_op<>());
  165. // remove duplicate turns
  166. turns::remove_duplicate_turns
  167. <
  168. Turns, EnableRemoveDuplicateTurns
  169. >::apply(turns);
  170. return detail::overlay::following::linear::follow
  171. <
  172. LinestringOut,
  173. LinearGeometry1,
  174. LinearGeometry2,
  175. OverlayTypeForFollow,
  176. FollowIsolatedPoints,
  177. !EnableFilterContinueTurns || OverlayType == overlay_intersection
  178. >::apply(linear1, linear2, boost::begin(turns), boost::end(turns),
  179. oit, strategy.get_side_strategy());
  180. }
  181. public:
  182. template
  183. <
  184. typename RobustPolicy, typename OutputIterator, typename Strategy
  185. >
  186. static inline OutputIterator apply(Linear1 const& linear1,
  187. Linear2 const& linear2,
  188. RobustPolicy const& robust_policy,
  189. OutputIterator oit,
  190. Strategy const& strategy)
  191. {
  192. typedef typename detail::relate::turns::get_turns
  193. <
  194. Linear1,
  195. Linear2,
  196. detail::get_turns::get_turn_info_type
  197. <
  198. Linear1,
  199. Linear2,
  200. assign_policy
  201. >
  202. >::template turn_info_type<Strategy, RobustPolicy>::type turn_info;
  203. typedef std::vector<turn_info> turns_container;
  204. turns_container turns;
  205. compute_turns(turns, linear1, linear2, strategy, robust_policy);
  206. if ( turns.empty() )
  207. {
  208. // the two linear geometries are disjoint
  209. return linear_linear_no_intersections
  210. <
  211. LinestringOut,
  212. OverlayType,
  213. Linear1,
  214. typename tag<Linear1>::type
  215. >::apply(linear1, oit);
  216. }
  217. return sort_and_follow_turns
  218. <
  219. OverlayType,
  220. EnableFollowIsolatedPoints
  221. && OverlayType == overlay_intersection
  222. >(turns, linear1, linear2, oit, strategy);
  223. }
  224. };
  225. template
  226. <
  227. typename Linear1,
  228. typename Linear2,
  229. typename LinestringOut,
  230. bool EnableFilterContinueTurns,
  231. bool EnableRemoveDuplicateTurns,
  232. bool EnableDegenerateTurns,
  233. bool EnableFollowIsolatedPoints
  234. >
  235. struct linear_linear_linestring
  236. <
  237. Linear1, Linear2, LinestringOut, overlay_union,
  238. EnableFilterContinueTurns, EnableRemoveDuplicateTurns,
  239. EnableDegenerateTurns, EnableFollowIsolatedPoints
  240. >
  241. {
  242. template
  243. <
  244. typename RobustPolicy, typename OutputIterator, typename Strategy
  245. >
  246. static inline OutputIterator apply(Linear1 const& linear1,
  247. Linear2 const& linear2,
  248. RobustPolicy const& robust_policy,
  249. OutputIterator oit,
  250. Strategy const& strategy)
  251. {
  252. oit = linear_linear_no_intersections
  253. <
  254. LinestringOut,
  255. overlay_difference,
  256. Linear1,
  257. typename tag<Linear1>::type
  258. >::apply(linear1, oit);
  259. return linear_linear_linestring
  260. <
  261. Linear2, Linear1, LinestringOut, overlay_difference,
  262. EnableFilterContinueTurns, EnableRemoveDuplicateTurns,
  263. EnableDegenerateTurns, EnableFollowIsolatedPoints
  264. >::apply(linear2, linear1, robust_policy, oit, strategy);
  265. }
  266. };
  267. }} // namespace detail::overlay
  268. #endif // DOXYGEN_NO_DETAIL
  269. }} // namespace boost::geometry
  270. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_LINEAR_LINEAR_HPP