summaryrefslogtreecommitdiff
path: root/boost/geometry/strategies/geographic/area.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/strategies/geographic/area.hpp')
-rw-r--r--boost/geometry/strategies/geographic/area.hpp116
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