diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
commit | b8cf34c691623e4ec329053cbbf68522a855882d (patch) | |
tree | 34da08632a99677f6b79ecb65e5b655a5b69a67f /boost/geometry/strategies/spherical/area.hpp | |
parent | 3fdc3e5ee96dca5b11d1694975a65200787eab86 (diff) | |
download | boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.gz boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.bz2 boost-b8cf34c691623e4ec329053cbbf68522a855882d.zip |
Imported Upstream version 1.67.0upstream/1.67.0
Diffstat (limited to 'boost/geometry/strategies/spherical/area.hpp')
-rw-r--r-- | boost/geometry/strategies/spherical/area.hpp | 120 |
1 files changed, 66 insertions, 54 deletions
diff --git a/boost/geometry/strategies/spherical/area.hpp b/boost/geometry/strategies/spherical/area.hpp index 1ab61b644f..d12ed9498f 100644 --- a/boost/geometry/strategies/spherical/area.hpp +++ b/boost/geometry/strategies/spherical/area.hpp @@ -1,6 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2016-2017 Oracle and/or its affiliates. +// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. + +// Copyright (c) 2016-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -13,9 +15,9 @@ #include <boost/geometry/formulas/area_formulas.hpp> -#include <boost/geometry/core/radius.hpp> -#include <boost/geometry/core/srs.hpp> +#include <boost/geometry/srs/sphere.hpp> #include <boost/geometry/strategies/area.hpp> +#include <boost/geometry/strategies/spherical/get_radius.hpp> namespace boost { namespace geometry @@ -24,11 +26,12 @@ namespace boost { namespace geometry namespace strategy { namespace area { + /*! \brief Spherical area calculation \ingroup strategies \details Calculates area on the surface of a sphere using the trapezoidal rule -\tparam PointOfSegment \tparam_segment_point +\tparam RadiusTypeOrSphere \tparam_radius_or_sphere \tparam CalculationType \tparam_calculation \qbk{ @@ -38,7 +41,7 @@ namespace strategy { namespace area */ template < - typename PointOfSegment, + typename RadiusTypeOrSphere = double, typename CalculationType = void > class spherical @@ -46,34 +49,35 @@ class spherical // Enables special handling of long segments static const bool LongSegment = false; -typedef typename boost::mpl::if_c - < - boost::is_void<CalculationType>::type::value, - typename select_most_precise +public: + template <typename Geometry> + struct result_type + : strategy::area::detail::result_type < - typename coordinate_type<PointOfSegment>::type, - double - >::type, - CalculationType - >::type CT; - -protected : - struct excess_sum + Geometry, + CalculationType + > + {}; + + template <typename Geometry> + class state { - CT m_sum; + friend class spherical; - // Keep track if encircles some pole - size_t m_crosses_prime_meridian; + typedef typename result_type<Geometry>::type return_type; - inline excess_sum() + public: + inline state() : m_sum(0) , m_crosses_prime_meridian(0) {} - template <typename SphereType> - inline CT area(SphereType sphere) const + + private: + template <typename RadiusType> + inline return_type area(RadiusType const& r) const { - CT result; - CT radius = geometry::get_radius<0>(sphere); + return_type result; + return_type radius = r; // Encircles pole if(m_crosses_prime_meridian % 2 == 1) @@ -81,12 +85,12 @@ protected : size_t times_crosses_prime_meridian = 1 + (m_crosses_prime_meridian / 2); - result = CT(2) - * geometry::math::pi<CT>() + result = return_type(2) + * geometry::math::pi<return_type>() * times_crosses_prime_meridian - geometry::math::abs(m_sum); - if(geometry::math::sign<CT>(m_sum) == 1) + if(geometry::math::sign<return_type>(m_sum) == 1) { result = - result; } @@ -99,54 +103,62 @@ protected : return result; } + + return_type m_sum; + + // Keep track if encircles some pole + size_t m_crosses_prime_meridian; }; public : - typedef CT return_type; - typedef PointOfSegment segment_point_type; - typedef excess_sum state_type; - typedef geometry::srs::sphere<CT> sphere_type; // For backward compatibility reasons the radius is set to 1 inline spherical() - : m_sphere(1.0) - {} - - template <typename T> - explicit inline spherical(geometry::srs::sphere<T> const& sphere) - : m_sphere(geometry::get_radius<0>(sphere)) + : m_radius(1.0) {} - explicit inline spherical(CT const& radius) - : m_sphere(radius) + template <typename RadiusOrSphere> + explicit inline spherical(RadiusOrSphere const& radius_or_sphere) + : m_radius(strategy_detail::get_radius + < + RadiusOrSphere + >::apply(radius_or_sphere)) {} + template <typename PointOfSegment, typename Geometry> inline void apply(PointOfSegment const& p1, PointOfSegment const& p2, - excess_sum& state) const + state<Geometry>& st) const { if (! geometry::math::equals(get<0>(p1), get<0>(p2))) { - typedef geometry::formula::area_formulas<CT> area_formulas; + typedef geometry::formula::area_formulas + < + typename result_type<Geometry>::type + > area_formulas; - state.m_sum += area_formulas::template spherical<LongSegment>(p1, p2); + st.m_sum += area_formulas::template spherical<LongSegment>(p1, p2); // Keep track whenever a segment crosses the prime meridian if (area_formulas::crosses_prime_meridian(p1, p2)) { - state.m_crosses_prime_meridian++; + st.m_crosses_prime_meridian++; } } } - inline return_type result(excess_sum const& state) const + template <typename Geometry> + inline typename result_type<Geometry>::type + result(state<Geometry> const& st) const { - return state.area(m_sphere); + return st.area(m_radius); } private : - /// srs Sphere - sphere_type m_sphere; + typename strategy_detail::get_radius + < + RadiusTypeOrSphere + >::type m_radius; }; #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS @@ -155,17 +167,17 @@ namespace services { -template <typename Point> -struct default_strategy<spherical_equatorial_tag, Point> +template <> +struct default_strategy<spherical_equatorial_tag> { - typedef strategy::area::spherical<Point> type; + typedef strategy::area::spherical<> type; }; // Note: spherical polar coordinate system requires "get_as_radian_equatorial" -template <typename Point> -struct default_strategy<spherical_polar_tag, Point> +template <> +struct default_strategy<spherical_polar_tag> { - typedef strategy::area::spherical<Point> type; + typedef strategy::area::spherical<> type; }; } // namespace services |