geographic.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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_GEOGRAPHIC_HPP
  8. #define BOOST_GEOMETRY_STRATEGIES_RELATE_GEOGRAPHIC_HPP
  9. // TEMP - move to strategy
  10. #include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
  11. #include <boost/geometry/strategies/cartesian/box_in_box.hpp>
  12. #include <boost/geometry/strategies/geographic/intersection.hpp>
  13. #include <boost/geometry/strategies/geographic/point_in_poly_winding.hpp>
  14. #include <boost/geometry/strategies/spherical/point_in_point.hpp>
  15. #include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
  16. #include <boost/geometry/strategies/distance/detail.hpp>
  17. #include <boost/geometry/strategies/distance/services.hpp>
  18. #include <boost/geometry/strategies/envelope/geographic.hpp>
  19. #include <boost/geometry/strategies/relate/services.hpp>
  20. #include <boost/geometry/strategies/detail.hpp>
  21. #include <boost/geometry/strategy/geographic/area.hpp>
  22. #include <boost/geometry/strategy/geographic/area_box.hpp>
  23. #include <boost/geometry/util/type_traits.hpp>
  24. namespace boost { namespace geometry
  25. {
  26. namespace strategies { namespace relate
  27. {
  28. template
  29. <
  30. typename FormulaPolicy = strategy::andoyer,
  31. typename Spheroid = srs::spheroid<double>,
  32. typename CalculationType = void
  33. >
  34. class geographic
  35. : public strategies::envelope::geographic<FormulaPolicy, Spheroid, CalculationType>
  36. {
  37. using base_t = strategies::envelope::geographic<FormulaPolicy, Spheroid, CalculationType>;
  38. public:
  39. geographic() = default;
  40. explicit geographic(Spheroid const& spheroid)
  41. : base_t(spheroid)
  42. {}
  43. // area
  44. template <typename Geometry>
  45. auto area(Geometry const&,
  46. std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr) const
  47. {
  48. return strategy::area::geographic
  49. <
  50. FormulaPolicy,
  51. strategy::default_order<FormulaPolicy>::value,
  52. Spheroid, CalculationType
  53. >(base_t::m_spheroid);
  54. }
  55. template <typename Geometry>
  56. auto area(Geometry const&,
  57. std::enable_if_t<util::is_box<Geometry>::value> * = nullptr) const
  58. {
  59. return strategy::area::geographic_box
  60. <
  61. Spheroid, CalculationType
  62. >(base_t::m_spheroid);
  63. }
  64. template <typename Geometry1, typename Geometry2>
  65. auto comparable_distance(Geometry1 const&, Geometry2 const&,
  66. distance::detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr) const
  67. {
  68. return strategy::distance::geographic
  69. <
  70. FormulaPolicy, Spheroid, CalculationType
  71. >(base_t::m_spheroid);
  72. }
  73. // covered_by
  74. template <typename Geometry1, typename Geometry2>
  75. static auto covered_by(Geometry1 const&, Geometry2 const&,
  76. std::enable_if_t
  77. <
  78. util::is_pointlike<Geometry1>::value
  79. && util::is_box<Geometry2>::value
  80. > * = nullptr)
  81. {
  82. return strategy::covered_by::spherical_point_box();
  83. }
  84. template <typename Geometry1, typename Geometry2>
  85. static auto covered_by(Geometry1 const&, Geometry2 const&,
  86. std::enable_if_t
  87. <
  88. util::is_box<Geometry1>::value
  89. && util::is_box<Geometry2>::value
  90. > * = nullptr)
  91. {
  92. return strategy::covered_by::spherical_box_box();
  93. }
  94. // disjoint
  95. template <typename Geometry1, typename Geometry2>
  96. static auto disjoint(Geometry1 const&, Geometry2 const&,
  97. std::enable_if_t
  98. <
  99. util::is_box<Geometry1>::value
  100. && util::is_box<Geometry2>::value
  101. > * = nullptr)
  102. {
  103. return strategy::disjoint::spherical_box_box();
  104. }
  105. template <typename Geometry1, typename Geometry2>
  106. auto disjoint(Geometry1 const&, Geometry2 const&,
  107. std::enable_if_t
  108. <
  109. util::is_segment<Geometry1>::value
  110. && util::is_box<Geometry2>::value
  111. > * = nullptr) const
  112. {
  113. // NOTE: Inconsistent name
  114. // The only disjoint(Seg, Box) strategy that takes CalculationType.
  115. return strategy::disjoint::segment_box_geographic
  116. <
  117. FormulaPolicy, Spheroid, CalculationType
  118. >(base_t::m_spheroid);
  119. }
  120. // relate
  121. template <typename Geometry1, typename Geometry2>
  122. static auto relate(Geometry1 const&, Geometry2 const&,
  123. std::enable_if_t
  124. <
  125. util::is_pointlike<Geometry1>::value
  126. && util::is_pointlike<Geometry2>::value
  127. > * = nullptr)
  128. {
  129. return strategy::within::spherical_point_point();
  130. }
  131. template <typename Geometry1, typename Geometry2>
  132. auto relate(Geometry1 const&, Geometry2 const&,
  133. std::enable_if_t
  134. <
  135. util::is_pointlike<Geometry1>::value
  136. && ( util::is_linear<Geometry2>::value
  137. || util::is_polygonal<Geometry2>::value )
  138. > * = nullptr) const
  139. {
  140. return strategy::within::geographic_winding
  141. <
  142. void, void, FormulaPolicy, Spheroid, CalculationType
  143. >(base_t::m_spheroid);
  144. }
  145. //template <typename Geometry1, typename Geometry2>
  146. auto relate(/*Geometry1 const&, Geometry2 const&,
  147. std::enable_if_t
  148. <
  149. ( util::is_linear<Geometry1>::value
  150. || util::is_polygonal<Geometry1>::value )
  151. && ( util::is_linear<Geometry2>::value
  152. || util::is_polygonal<Geometry2>::value )
  153. > * = nullptr*/) const
  154. {
  155. return strategy::intersection::geographic_segments
  156. <
  157. FormulaPolicy,
  158. strategy::default_order<FormulaPolicy>::value,
  159. Spheroid, CalculationType
  160. >(base_t::m_spheroid);
  161. }
  162. // side
  163. auto side() const
  164. {
  165. return strategy::side::geographic
  166. <
  167. FormulaPolicy, Spheroid, CalculationType
  168. >(base_t::m_spheroid);
  169. }
  170. // within
  171. template <typename Geometry1, typename Geometry2>
  172. static auto within(Geometry1 const&, Geometry2 const&,
  173. std::enable_if_t
  174. <
  175. util::is_pointlike<Geometry1>::value
  176. && util::is_box<Geometry2>::value
  177. > * = nullptr)
  178. {
  179. return strategy::within::spherical_point_box();
  180. }
  181. template <typename Geometry1, typename Geometry2>
  182. static auto within(Geometry1 const&, Geometry2 const&,
  183. std::enable_if_t
  184. <
  185. util::is_box<Geometry1>::value
  186. && util::is_box<Geometry2>::value
  187. > * = nullptr)
  188. {
  189. return strategy::within::spherical_box_box();
  190. }
  191. template <typename ComparePolicy, typename EqualsPolicy>
  192. using compare_type = typename strategy::compare::spherical
  193. <
  194. ComparePolicy,
  195. EqualsPolicy,
  196. -1
  197. >;
  198. };
  199. namespace services
  200. {
  201. template <typename Geometry1, typename Geometry2>
  202. struct default_strategy<Geometry1, Geometry2, geographic_tag, geographic_tag>
  203. {
  204. using type = strategies::relate::geographic<>;
  205. };
  206. template <typename FormulaPolicy, typename Spheroid, typename CalculationType>
  207. struct strategy_converter<strategy::disjoint::segment_box_geographic<FormulaPolicy, Spheroid, CalculationType>>
  208. {
  209. static auto get(strategy::disjoint::segment_box_geographic<FormulaPolicy, Spheroid, CalculationType> const& s)
  210. {
  211. return strategies::relate::geographic
  212. <
  213. FormulaPolicy,
  214. Spheroid,
  215. CalculationType
  216. >(s.model());
  217. }
  218. };
  219. template <typename P1, typename P2, typename FormulaPolicy, typename Spheroid, typename CalculationType>
  220. struct strategy_converter<strategy::within::geographic_winding<P1, P2, FormulaPolicy, Spheroid, CalculationType>>
  221. {
  222. static auto get(strategy::within::geographic_winding<P1, P2, FormulaPolicy, Spheroid, CalculationType> const& s)
  223. {
  224. return strategies::relate::geographic
  225. <
  226. FormulaPolicy,
  227. Spheroid,
  228. CalculationType
  229. >(s.model());
  230. }
  231. };
  232. template <typename FormulaPolicy, std::size_t SeriesOrder, typename Spheroid, typename CalculationType>
  233. struct strategy_converter<strategy::intersection::geographic_segments<FormulaPolicy, SeriesOrder, Spheroid, CalculationType>>
  234. {
  235. struct altered_strategy
  236. : strategies::relate::geographic<FormulaPolicy, Spheroid, CalculationType>
  237. {
  238. typedef strategies::relate::geographic<FormulaPolicy, Spheroid, CalculationType> base_t;
  239. explicit altered_strategy(Spheroid const& spheroid)
  240. : base_t(spheroid)
  241. {}
  242. template <typename Geometry>
  243. auto area(Geometry const&) const
  244. {
  245. return strategy::area::geographic
  246. <
  247. FormulaPolicy, SeriesOrder, Spheroid, CalculationType
  248. >(base_t::m_spheroid);
  249. }
  250. using base_t::relate;
  251. auto relate(/*...*/) const
  252. {
  253. return strategy::intersection::geographic_segments
  254. <
  255. FormulaPolicy, SeriesOrder, Spheroid, CalculationType
  256. >(base_t::m_spheroid);
  257. }
  258. template <typename ComparePolicy, typename EqualsPolicy>
  259. using compare_type = typename strategy::compare::spherical
  260. <
  261. ComparePolicy,
  262. EqualsPolicy,
  263. -1
  264. >;
  265. };
  266. static auto get(strategy::intersection::geographic_segments<FormulaPolicy, SeriesOrder, Spheroid, CalculationType> const& s)
  267. {
  268. return altered_strategy(s.model());
  269. }
  270. };
  271. template <typename FormulaPolicy, typename Spheroid, typename CalculationType>
  272. struct strategy_converter<strategy::within::geographic_point_box_by_side<FormulaPolicy, Spheroid, CalculationType>>
  273. {
  274. struct altered_strategy
  275. : strategies::relate::geographic<FormulaPolicy, Spheroid, CalculationType>
  276. {
  277. altered_strategy(Spheroid const& spheroid)
  278. : strategies::relate::geographic<FormulaPolicy, Spheroid, CalculationType>(spheroid)
  279. {}
  280. template <typename Geometry1, typename Geometry2>
  281. auto covered_by(Geometry1 const&, Geometry2 const&,
  282. std::enable_if_t
  283. <
  284. util::is_pointlike<Geometry1>::value
  285. && util::is_box<Geometry2>::value
  286. > * = nullptr) const
  287. {
  288. return strategy::covered_by::geographic_point_box_by_side
  289. <
  290. FormulaPolicy, Spheroid, CalculationType
  291. >(this->model());
  292. }
  293. template <typename Geometry1, typename Geometry2>
  294. auto within(Geometry1 const&, Geometry2 const&,
  295. std::enable_if_t
  296. <
  297. util::is_pointlike<Geometry1>::value
  298. && util::is_box<Geometry2>::value
  299. > * = nullptr) const
  300. {
  301. return strategy::within::geographic_point_box_by_side
  302. <
  303. FormulaPolicy, Spheroid, CalculationType
  304. >(this->model());
  305. }
  306. };
  307. static auto get(strategy::covered_by::geographic_point_box_by_side<FormulaPolicy, Spheroid, CalculationType> const& s)
  308. {
  309. return altered_strategy(s.model());
  310. }
  311. static auto get(strategy::within::geographic_point_box_by_side<FormulaPolicy, Spheroid, CalculationType> const& s)
  312. {
  313. return altered_strategy(s.model());
  314. }
  315. };
  316. template <typename CalculationType>
  317. struct strategy_converter<strategy::covered_by::geographic_point_box_by_side<CalculationType>>
  318. : strategy_converter<strategy::within::geographic_point_box_by_side<CalculationType>>
  319. {};
  320. } // namespace services
  321. }} // namespace strategies::relate
  322. }} // namespace boost::geometry
  323. #endif // BOOST_GEOMETRY_STRATEGIES_RELATE_GEOGRAPHIC_HPP