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/geographic/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/geographic/area.hpp')
-rw-r--r-- | boost/geometry/strategies/geographic/area.hpp | 116 |
1 files changed, 65 insertions, 51 deletions
diff --git a/boost/geometry/strategies/geographic/area.hpp b/boost/geometry/strategies/geographic/area.hpp index 40d6c8243e..ac7d933ce7 100644 --- a/boost/geometry/strategies/geographic/area.hpp +++ b/boost/geometry/strategies/geographic/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 @@ -12,7 +14,7 @@ #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_AREA_HPP -#include <boost/geometry/core/srs.hpp> +#include <boost/geometry/srs/spheroid.hpp> #include <boost/geometry/formulas/area_formulas.hpp> #include <boost/geometry/formulas/authalic_radius_sqr.hpp> @@ -32,7 +34,6 @@ namespace strategy { namespace area \ingroup strategies \details Geographic area calculation by trapezoidal rule plus integral approximation that gives the ellipsoidal correction -\tparam PointOfSegment \tparam_segment_point \tparam FormulaPolicy Formula used to calculate azimuths \tparam SeriesOrder The order of approximation of the geodesic integral \tparam Spheroid The spheroid model @@ -43,12 +44,12 @@ namespace strategy { namespace area \qbk{ [heading See also] -[link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)] +\* [link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)] +\* [link geometry.reference.srs.srs_spheroid srs::spheroid] } */ template < - typename PointOfSegment, typename FormulaPolicy = strategy::andoyer, std::size_t SeriesOrder = strategy::default_order<FormulaPolicy>::value, typename Spheroid = srs::spheroid<double>, @@ -63,58 +64,67 @@ class geographic //Select default types in case they are not set - 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; + Geometry, + CalculationType + > + {}; protected : struct spheroid_constants { + typedef typename boost::mpl::if_c + < + boost::is_void<CalculationType>::value, + typename geometry::radius_type<Spheroid>::type, + CalculationType + >::type calc_t; + Spheroid m_spheroid; - CT const m_a2; // squared equatorial radius - CT const m_e2; // squared eccentricity - CT const m_ep2; // squared second eccentricity - CT const m_ep; // second eccentricity - CT const m_c2; // squared authalic radius + calc_t const m_a2; // squared equatorial radius + calc_t const m_e2; // squared eccentricity + calc_t const m_ep2; // squared second eccentricity + calc_t const m_ep; // second eccentricity + calc_t const m_c2; // squared authalic radius inline spheroid_constants(Spheroid const& spheroid) : m_spheroid(spheroid) , m_a2(math::sqr(get_radius<0>(spheroid))) - , m_e2(formula::eccentricity_sqr<CT>(spheroid)) - , m_ep2(m_e2 / (CT(1.0) - m_e2)) + , m_e2(formula::eccentricity_sqr<calc_t>(spheroid)) + , m_ep2(m_e2 / (calc_t(1.0) - m_e2)) , m_ep(math::sqrt(m_ep2)) , m_c2(formula_dispatch::authalic_radius_sqr < - CT, Spheroid, srs_spheroid_tag + calc_t, Spheroid, srs_spheroid_tag >::apply(m_a2, m_e2)) {} }; - struct area_sums +public: + template <typename Geometry> + class state { - CT m_excess_sum; - CT m_correction_sum; + friend class geographic; - // Keep track if encircles some pole - std::size_t m_crosses_prime_meridian; + typedef typename result_type<Geometry>::type return_type; - inline area_sums() + public: + inline state() : m_excess_sum(0) , m_correction_sum(0) , m_crosses_prime_meridian(0) {} - inline CT area(spheroid_constants spheroid_const) const + + private: + inline return_type area(spheroid_constants const& spheroid_const) const { - CT result; + return_type result; - CT sum = spheroid_const.m_c2 * m_excess_sum + return_type sum = spheroid_const.m_c2 * m_excess_sum + spheroid_const.m_e2 * spheroid_const.m_a2 * m_correction_sum; // If encircles some pole @@ -123,13 +133,13 @@ protected : std::size_t times_crosses_prime_meridian = 1 + (m_crosses_prime_meridian / 2); - result = CT(2.0) - * geometry::math::pi<CT>() + result = return_type(2.0) + * geometry::math::pi<return_type>() * spheroid_const.m_c2 - * CT(times_crosses_prime_meridian) + * return_type(times_crosses_prime_meridian) - geometry::math::abs(sum); - if (geometry::math::sign<CT>(sum) == 1) + if (geometry::math::sign<return_type>(sum) == 1) { result = - result; } @@ -142,48 +152,52 @@ protected : return result; } + + return_type m_excess_sum; + return_type m_correction_sum; + + // Keep track if encircles some pole + std::size_t m_crosses_prime_meridian; }; public : - typedef CT return_type; - typedef PointOfSegment segment_point_type; - typedef area_sums state_type; - explicit inline geographic(Spheroid const& spheroid = Spheroid()) : m_spheroid_constants(spheroid) {} + template <typename PointOfSegment, typename Geometry> inline void apply(PointOfSegment const& p1, PointOfSegment const& p2, - area_sums& state) const + state<Geometry>& st) const { - if (! geometry::math::equals(get<0>(p1), get<0>(p2))) { - typedef geometry::formula::area_formulas < - CT, SeriesOrder, ExpandEpsN + typename result_type<Geometry>::type, + SeriesOrder, ExpandEpsN > area_formulas; typename area_formulas::return_type_ellipsoidal result = area_formulas::template ellipsoidal<FormulaPolicy::template inverse> (p1, p2, m_spheroid_constants); - state.m_excess_sum += result.spherical_term; - state.m_correction_sum += result.ellipsoidal_term; + st.m_excess_sum += result.spherical_term; + st.m_correction_sum += result.ellipsoidal_term; // 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(area_sums const& state) const + template <typename Geometry> + inline typename result_type<Geometry>::type + result(state<Geometry> const& st) const { - return state.area(m_spheroid_constants); + return st.area(m_spheroid_constants); } private: @@ -197,10 +211,10 @@ namespace services { -template <typename Point> -struct default_strategy<geographic_tag, Point> +template <> +struct default_strategy<geographic_tag> { - typedef strategy::area::geographic<Point> type; + typedef strategy::area::geographic<> type; }; #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS |