1 // Boost.Geometry
2 
3 // Copyright (c) 2020-2021, Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
6 
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
9 
10 #ifndef BOOST_GEOMETRY_STRATEGIES_AREA_GEOGRAPHIC_HPP
11 #define BOOST_GEOMETRY_STRATEGIES_AREA_GEOGRAPHIC_HPP
12 
13 
14 #include <boost/geometry/strategy/geographic/area.hpp>
15 #include <boost/geometry/strategy/geographic/area_box.hpp>
16 
17 #include <boost/geometry/strategies/area/services.hpp>
18 #include <boost/geometry/strategies/detail.hpp>
19 
20 
21 namespace boost { namespace geometry
22 {
23 
24 namespace strategies { namespace area
25 {
26 
27 template
28 <
29     typename FormulaPolicy = strategy::andoyer,
30     typename Spheroid = srs::spheroid<double>,
31     typename CalculationType = void
32 >
33 class geographic
34     : public strategies::detail::geographic_base<Spheroid>
35 {
36     using base_t = strategies::detail::geographic_base<Spheroid>;
37 
38 public:
39     geographic() = default;
40 
geographic(Spheroid const & spheroid)41     explicit geographic(Spheroid const& spheroid)
42         : base_t(spheroid)
43     {}
44 
45     template <typename Geometry>
area(Geometry const &,std::enable_if_t<!util::is_box<Geometry>::value> * =nullptr) const46     auto area(Geometry const&,
47               std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr) const
48     {
49         return strategy::area::geographic
50             <
51                 FormulaPolicy,
52                 strategy::default_order<FormulaPolicy>::value,
53                 Spheroid, CalculationType
54             >(base_t::m_spheroid);
55     }
56 
57     template <typename Geometry>
area(Geometry const &,std::enable_if_t<util::is_box<Geometry>::value> * =nullptr) const58     auto area(Geometry const&,
59               std::enable_if_t<util::is_box<Geometry>::value> * = nullptr) const
60     {
61         return strategy::area::geographic_box
62             <
63                 Spheroid, CalculationType
64             >(base_t::m_spheroid);
65     }
66 };
67 
68 
69 namespace services
70 {
71 
72 template <typename Geometry>
73 struct default_strategy<Geometry, geographic_tag>
74 {
75     using type = strategies::area::geographic<>;
76 };
77 
78 
79 template <typename FP, std::size_t SO, typename S, typename CT>
80 struct strategy_converter<strategy::area::geographic<FP, SO, S, CT> >
81 {
82     struct altered_strategy
83         : strategies::area::geographic<FP, S, CT>
84     {
altered_strategyboost::geometry::strategies::area::services::strategy_converter::altered_strategy85         explicit altered_strategy(S const& spheroid)
86             : strategies::area::geographic<FP, S, CT>(spheroid)
87         {}
88 
89         using strategies::area::geographic<FP, S, CT>::area;
90 
91         template <typename Geometry>
areaboost::geometry::strategies::area::services::strategy_converter::altered_strategy92         auto area(Geometry const&,
93                   std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr) const
94         {
95             return strategy::area::geographic<FP, SO, S, CT>(this->m_spheroid);
96         }
97     };
98 
getboost::geometry::strategies::area::services::strategy_converter99     static auto get(strategy::area::geographic<FP, SO, S, CT> const& strategy)
100     {
101         return altered_strategy(strategy.model());
102     }
103 };
104 
105 } // namespace services
106 
107 }} // namespace strategies::area
108 
109 }} // namespace boost::geometry
110 
111 #endif // BOOST_GEOMETRY_STRATEGIES_AREA_GEOGRAPHIC_HPP
112