cartesian.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. // Boost.Geometry
  2. // Copyright (c) 2020-2023, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_GEOMETRY_STRATEGIES_RELATE_CARTESIAN_HPP
  8. #define BOOST_GEOMETRY_STRATEGIES_RELATE_CARTESIAN_HPP
  9. // TEMP - move to strategy
  10. #include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
  11. #include <boost/geometry/strategies/cartesian/intersection.hpp>
  12. #include <boost/geometry/strategies/cartesian/box_in_box.hpp>
  13. #include <boost/geometry/strategies/cartesian/point_in_point.hpp>
  14. #include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
  15. #include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
  16. #include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
  17. #include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
  18. #include <boost/geometry/strategies/envelope/cartesian.hpp>
  19. #include <boost/geometry/strategies/relate/services.hpp>
  20. #include <boost/geometry/strategies/detail.hpp>
  21. #include <boost/geometry/strategy/cartesian/area.hpp>
  22. #include <boost/geometry/strategy/cartesian/side_robust.hpp>
  23. #include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
  24. #include <boost/geometry/strategy/cartesian/area_box.hpp>
  25. #include <boost/geometry/util/type_traits.hpp>
  26. namespace boost { namespace geometry
  27. {
  28. namespace strategies { namespace relate
  29. {
  30. template <typename CalculationType = void>
  31. class cartesian
  32. : public strategies::envelope::cartesian<CalculationType>
  33. {
  34. public:
  35. //area
  36. template <typename Geometry>
  37. static auto area(Geometry const&,
  38. std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr)
  39. {
  40. return strategy::area::cartesian<CalculationType>();
  41. }
  42. template <typename Geometry>
  43. static auto area(Geometry const&,
  44. std::enable_if_t<util::is_box<Geometry>::value> * = nullptr)
  45. {
  46. return strategy::area::cartesian_box<CalculationType>();
  47. }
  48. // covered_by
  49. template <typename Geometry1, typename Geometry2>
  50. static auto covered_by(Geometry1 const&, Geometry2 const&,
  51. std::enable_if_t
  52. <
  53. util::is_pointlike<Geometry1>::value
  54. && util::is_box<Geometry2>::value
  55. > * = nullptr)
  56. {
  57. return strategy::covered_by::cartesian_point_box();
  58. }
  59. template <typename Geometry1, typename Geometry2>
  60. static auto covered_by(Geometry1 const&, Geometry2 const&,
  61. std::enable_if_t
  62. <
  63. util::is_box<Geometry1>::value
  64. && util::is_box<Geometry2>::value
  65. > * = nullptr)
  66. {
  67. return strategy::covered_by::cartesian_box_box();
  68. }
  69. // disjoint
  70. template <typename Geometry1, typename Geometry2>
  71. static auto disjoint(Geometry1 const&, Geometry2 const&,
  72. std::enable_if_t
  73. <
  74. util::is_box<Geometry1>::value
  75. && util::is_box<Geometry2>::value
  76. > * = nullptr)
  77. {
  78. return strategy::disjoint::cartesian_box_box();
  79. }
  80. template <typename Geometry1, typename Geometry2>
  81. static auto disjoint(Geometry1 const&, Geometry2 const&,
  82. std::enable_if_t
  83. <
  84. util::is_segment<Geometry1>::value
  85. && util::is_box<Geometry2>::value
  86. > * = nullptr)
  87. {
  88. // NOTE: Inconsistent name.
  89. return strategy::disjoint::segment_box();
  90. }
  91. // relate
  92. template <typename Geometry1, typename Geometry2>
  93. static auto relate(Geometry1 const&, Geometry2 const&,
  94. std::enable_if_t
  95. <
  96. util::is_pointlike<Geometry1>::value
  97. && util::is_pointlike<Geometry2>::value
  98. > * = nullptr)
  99. {
  100. return strategy::within::cartesian_point_point();
  101. }
  102. template <typename Geometry1, typename Geometry2>
  103. static auto relate(Geometry1 const&, Geometry2 const&,
  104. std::enable_if_t
  105. <
  106. util::is_pointlike<Geometry1>::value
  107. && ( util::is_linear<Geometry2>::value
  108. || util::is_polygonal<Geometry2>::value )
  109. > * = nullptr)
  110. {
  111. return strategy::within::cartesian_winding<void, void, CalculationType>();
  112. }
  113. // The problem is that this strategy is often used with non-geometry ranges.
  114. // So dispatching only by geometry categories is impossible.
  115. // In the past it was taking two segments, now it takes 3-point sub-ranges.
  116. // So dispatching by segments is impossible.
  117. // It could be dispatched by (linear || polygonal || non-geometry point range).
  118. // For now implement as 0-parameter, special case relate.
  119. //template <typename Geometry1, typename Geometry2>
  120. static auto relate(/*Geometry1 const&, Geometry2 const&,
  121. std::enable_if_t
  122. <
  123. ( util::is_linear<Geometry1>::value
  124. || util::is_polygonal<Geometry1>::value )
  125. && ( util::is_linear<Geometry2>::value
  126. || util::is_polygonal<Geometry2>::value )
  127. > * = nullptr*/)
  128. {
  129. return strategy::intersection::cartesian_segments<CalculationType>();
  130. }
  131. // side
  132. static auto side()
  133. {
  134. using side_strategy_type
  135. = typename strategy::side::services::default_strategy
  136. <cartesian_tag, CalculationType>::type;
  137. return side_strategy_type();
  138. }
  139. // within
  140. template <typename Geometry1, typename Geometry2>
  141. static auto within(Geometry1 const&, Geometry2 const&,
  142. std::enable_if_t
  143. <
  144. util::is_pointlike<Geometry1>::value
  145. && util::is_box<Geometry2>::value
  146. > * = nullptr)
  147. {
  148. return strategy::within::cartesian_point_box();
  149. }
  150. template <typename Geometry1, typename Geometry2>
  151. static auto within(Geometry1 const&, Geometry2 const&,
  152. std::enable_if_t
  153. <
  154. util::is_box<Geometry1>::value
  155. && util::is_box<Geometry2>::value
  156. > * = nullptr)
  157. {
  158. return strategy::within::cartesian_box_box();
  159. }
  160. template <typename ComparePolicy, typename EqualsPolicy>
  161. using compare_type = typename strategy::compare::cartesian
  162. <
  163. ComparePolicy,
  164. EqualsPolicy,
  165. -1
  166. >;
  167. };
  168. namespace services
  169. {
  170. template <typename Geometry1, typename Geometry2>
  171. struct default_strategy<Geometry1, Geometry2, cartesian_tag, cartesian_tag>
  172. {
  173. using type = strategies::relate::cartesian<>;
  174. };
  175. template <>
  176. struct strategy_converter<strategy::within::cartesian_point_point>
  177. {
  178. static auto get(strategy::within::cartesian_point_point const& )
  179. {
  180. return strategies::relate::cartesian<>();
  181. }
  182. };
  183. template <>
  184. struct strategy_converter<strategy::within::cartesian_point_box>
  185. {
  186. static auto get(strategy::within::cartesian_point_box const&)
  187. {
  188. return strategies::relate::cartesian<>();
  189. }
  190. };
  191. template <>
  192. struct strategy_converter<strategy::covered_by::cartesian_point_box>
  193. {
  194. static auto get(strategy::covered_by::cartesian_point_box const&)
  195. {
  196. return strategies::relate::cartesian<>();
  197. }
  198. };
  199. template <>
  200. struct strategy_converter<strategy::covered_by::cartesian_box_box>
  201. {
  202. static auto get(strategy::covered_by::cartesian_box_box const&)
  203. {
  204. return strategies::relate::cartesian<>();
  205. }
  206. };
  207. template <>
  208. struct strategy_converter<strategy::disjoint::cartesian_box_box>
  209. {
  210. static auto get(strategy::disjoint::cartesian_box_box const&)
  211. {
  212. return strategies::relate::cartesian<>();
  213. }
  214. };
  215. template <>
  216. struct strategy_converter<strategy::disjoint::segment_box>
  217. {
  218. static auto get(strategy::disjoint::segment_box const&)
  219. {
  220. return strategies::relate::cartesian<>();
  221. }
  222. };
  223. template <>
  224. struct strategy_converter<strategy::within::cartesian_box_box>
  225. {
  226. static auto get(strategy::within::cartesian_box_box const&)
  227. {
  228. return strategies::relate::cartesian<>();
  229. }
  230. };
  231. template <typename P1, typename P2, typename CalculationType>
  232. struct strategy_converter<strategy::within::cartesian_winding<P1, P2, CalculationType>>
  233. {
  234. static auto get(strategy::within::cartesian_winding<P1, P2, CalculationType> const& )
  235. {
  236. return strategies::relate::cartesian<CalculationType>();
  237. }
  238. };
  239. template <typename CalculationType>
  240. struct strategy_converter<strategy::intersection::cartesian_segments<CalculationType>>
  241. {
  242. static auto get(strategy::intersection::cartesian_segments<CalculationType> const& )
  243. {
  244. return strategies::relate::cartesian<CalculationType>();
  245. }
  246. };
  247. template <typename CalculationType>
  248. struct strategy_converter<strategy::within::cartesian_point_box_by_side<CalculationType>>
  249. {
  250. struct altered_strategy
  251. : strategies::relate::cartesian<CalculationType>
  252. {
  253. template <typename Geometry1, typename Geometry2>
  254. static auto covered_by(Geometry1 const&, Geometry2 const&,
  255. std::enable_if_t
  256. <
  257. util::is_pointlike<Geometry1>::value
  258. && util::is_box<Geometry2>::value
  259. > * = nullptr)
  260. {
  261. return strategy::covered_by::cartesian_point_box_by_side<CalculationType>();
  262. }
  263. template <typename Geometry1, typename Geometry2>
  264. static auto within(Geometry1 const&, Geometry2 const&,
  265. std::enable_if_t
  266. <
  267. util::is_pointlike<Geometry1>::value
  268. && util::is_box<Geometry2>::value
  269. > * = nullptr)
  270. {
  271. return strategy::within::cartesian_point_box_by_side<CalculationType>();
  272. }
  273. };
  274. static auto get(strategy::covered_by::cartesian_point_box_by_side<CalculationType> const&)
  275. {
  276. return altered_strategy();
  277. }
  278. static auto get(strategy::within::cartesian_point_box_by_side<CalculationType> const&)
  279. {
  280. return altered_strategy();
  281. }
  282. };
  283. template <typename CalculationType>
  284. struct strategy_converter<strategy::covered_by::cartesian_point_box_by_side<CalculationType>>
  285. : strategy_converter<strategy::within::cartesian_point_box_by_side<CalculationType>>
  286. {};
  287. template <typename P1, typename P2, typename CalculationType>
  288. struct strategy_converter<strategy::within::franklin<P1, P2, CalculationType>>
  289. {
  290. struct altered_strategy
  291. : strategies::relate::cartesian<CalculationType>
  292. {
  293. template <typename Geometry1, typename Geometry2>
  294. static auto relate(Geometry1 const&, Geometry2 const&,
  295. std::enable_if_t
  296. <
  297. util::is_pointlike<Geometry1>::value
  298. && ( util::is_linear<Geometry2>::value
  299. || util::is_polygonal<Geometry2>::value )
  300. > * = nullptr)
  301. {
  302. return strategy::within::franklin<void, void, CalculationType>();
  303. }
  304. };
  305. static auto get(strategy::within::franklin<P1, P2, CalculationType> const&)
  306. {
  307. return altered_strategy();
  308. }
  309. };
  310. template <typename P1, typename P2, typename CalculationType>
  311. struct strategy_converter<strategy::within::crossings_multiply<P1, P2, CalculationType>>
  312. {
  313. struct altered_strategy
  314. : strategies::relate::cartesian<CalculationType>
  315. {
  316. template <typename Geometry1, typename Geometry2>
  317. static auto relate(Geometry1 const&, Geometry2 const&,
  318. std::enable_if_t
  319. <
  320. util::is_pointlike<Geometry1>::value
  321. && ( util::is_linear<Geometry2>::value
  322. || util::is_polygonal<Geometry2>::value )
  323. > * = nullptr)
  324. {
  325. return strategy::within::crossings_multiply<void, void, CalculationType>();
  326. }
  327. };
  328. static auto get(strategy::within::crossings_multiply<P1, P2, CalculationType> const&)
  329. {
  330. return altered_strategy();
  331. }
  332. };
  333. // TEMP used in distance segment/box
  334. template <typename CalculationType>
  335. struct strategy_converter<strategy::side::side_by_triangle<CalculationType>>
  336. {
  337. static auto get(strategy::side::side_by_triangle<CalculationType> const&)
  338. {
  339. return strategies::relate::cartesian<CalculationType>();
  340. }
  341. };
  342. template <typename CalculationType>
  343. struct strategy_converter<strategy::side::side_robust<CalculationType>>
  344. {
  345. static auto get(strategy::side::side_robust<CalculationType> const&)
  346. {
  347. return strategies::relate::cartesian<CalculationType>();
  348. }
  349. };
  350. } // namespace services
  351. }} // namespace strategies::relate
  352. }} // namespace boost::geometry
  353. #endif // BOOST_GEOMETRY_STRATEGIES_RELATE_CARTESIAN_HPP