$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r85057 - in trunk: boost/geometry/extensions/gis/geographic/strategies libs/geometry/extensions/test/gis/latlong
From: barend.gehrels_at_[hidden]
Date: 2013-07-17 09:32:12
Author: barendgehrels
Date: 2013-07-17 09:32:12 EDT (Wed, 17 Jul 2013)
New Revision: 85057
URL: http://svn.boost.org/trac/boost/changeset/85057
Log:
[geometry] adapted extension andoyer to new structure strategies
Text files modified: 
   trunk/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp |   218 +++++++++++++++++++-------------------- 
   trunk/libs/geometry/extensions/test/gis/latlong/andoyer.cpp           |    18 ++                                      
   2 files changed, 118 insertions(+), 118 deletions(-)
Modified: trunk/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp	Wed Jul 17 05:48:43 2013	(r85056)
+++ trunk/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp	2013-07-17 09:32:12 EDT (Wed, 17 Jul 2013)	(r85057)
@@ -30,8 +30,6 @@
 /*!
 \brief Point-point distance approximation taking flattening into account
 \ingroup distance
-\tparam Point1 \tparam_first_point
-\tparam Point2 \tparam_second_point
 \tparam CalculationType \tparam_calculation
 \author After Andoyer, 19xx, republished 1950, republished by Meeus, 1999
 \note Although not so well-known, the approximation is very good: in all cases the results
@@ -45,101 +43,109 @@
 */
 template
 <
-    typename Point1,
-    typename Point2 = Point1,
+    typename RadiusType,
     typename CalculationType = void
 >
 class andoyer
 {
-    public :
-    typedef typename promote_floating_point
-        <
-            typename select_calculation_type
-                <
-                    Point1,
-                    Point2,
-                    CalculationType
-                >::type
-        >::type calculation_type;
-
-        inline andoyer()
-            : m_ellipsoid()
-        {}
-
-        explicit inline andoyer(calculation_type f)
-            : m_ellipsoid(f)
-        {}
-
-        explicit inline andoyer(geometry::detail::ellipsoid<calculation_type> const& e)
-            : m_ellipsoid(e)
-        {}
+public :
+    template <typename Point1, typename Point2>
+    struct calculation_type
+        : promote_floating_point
+          <
+              typename select_calculation_type
+                  <
+                      Point1,
+                      Point2,
+                      CalculationType
+                  >::type
+          >
+    {};
+
+    inline andoyer()
+        : m_ellipsoid()
+    {}
+
+    explicit inline andoyer(RadiusType f)
+        : m_ellipsoid(f)
+    {}
+
+    explicit inline andoyer(geometry::detail::ellipsoid<RadiusType> const& e)
+        : m_ellipsoid(e)
+    {}
+
+
+    template <typename Point1, typename Point2>
+    inline typename calculation_type<Point1, Point2>::type
+    apply(Point1 const& point1, Point2 const& point2) const
+    {
+        return calc<typename calculation_type<Point1, Point2>::type>
+            (
+                get_as_radian<0>(point1), get_as_radian<1>(point1),
+                get_as_radian<0>(point2), get_as_radian<1>(point2)
+            );
+    }
 
+    inline geometry::detail::ellipsoid<RadiusType> ellipsoid() const
+    {
+        return m_ellipsoid;
+    }
 
-        inline calculation_type apply(Point1 const& point1, Point2 const& point2) const
-        {
-            return calc(get_as_radian<0>(point1), get_as_radian<1>(point1),
-                            get_as_radian<0>(point2), get_as_radian<1>(point2));
-        }
+    inline RadiusType radius() const
+    {
+        return m_ellipsoid.a();
+    }
 
-        inline geometry::detail::ellipsoid<calculation_type> ellipsoid() const
-        {
-            return m_ellipsoid;
-        }
 
-        inline calculation_type radius() const
+private :
+    geometry::detail::ellipsoid<RadiusType> m_ellipsoid;
+
+    template <typename CT, typename T>
+    inline CT calc(T const& lon1,
+                T const& lat1,
+                T const& lon2,
+                T const& lat2) const
+    {
+        CT const G = (lat1 - lat2) / 2.0;
+        CT const lambda = (lon1 - lon2) / 2.0;
+
+        if (geometry::math::equals(lambda, 0.0)
+            && geometry::math::equals(G, 0.0))
         {
-            return m_ellipsoid.a();
+            return 0.0;
         }
 
+        CT const F = (lat1 + lat2) / 2.0;
 
-    private :
-        geometry::detail::ellipsoid<calculation_type> m_ellipsoid;
+        CT const sinG2 = math::sqr(sin(G));
+        CT const cosG2 = math::sqr(cos(G));
+        CT const sinF2 = math::sqr(sin(F));
+        CT const cosF2 = math::sqr(cos(F));
+        CT const sinL2 = math::sqr(sin(lambda));
+        CT const cosL2 = math::sqr(cos(lambda));
+
+        CT const S = sinG2 * cosL2 + cosF2 * sinL2;
+        CT const C = cosG2 * cosL2 + sinF2 * sinL2;
+
+        CT const c0 = 0;
+        CT const c1 = 1;
+        CT const c2 = 2;
+        CT const c3 = 3;
 
-        inline calculation_type calc(calculation_type const& lon1,
-                    calculation_type const& lat1,
-                    calculation_type const& lon2,
-                    calculation_type const& lat2) const
+        if (geometry::math::equals(S, c0) || geometry::math::equals(C, c0))
         {
-            calculation_type const G = (lat1 - lat2) / 2.0;
-            calculation_type const lambda = (lon1 - lon2) / 2.0;
+            return c0;
+        }
 
-            if (geometry::math::equals(lambda, 0.0)
-                && geometry::math::equals(G, 0.0))
-            {
-                return 0.0;
-            }
-
-            calculation_type const F = (lat1 + lat2) / 2.0;
-
-            calculation_type const sinG2 = math::sqr(sin(G));
-            calculation_type const cosG2 = math::sqr(cos(G));
-            calculation_type const sinF2 = math::sqr(sin(F));
-            calculation_type const cosF2 = math::sqr(cos(F));
-            calculation_type const sinL2 = math::sqr(sin(lambda));
-            calculation_type const cosL2 = math::sqr(cos(lambda));
-
-            calculation_type const S = sinG2 * cosL2 + cosF2 * sinL2;
-            calculation_type const C = cosG2 * cosL2 + sinF2 * sinL2;
-
-            calculation_type const c0 = 0;
-            calculation_type const c1 = 1;
-            calculation_type const c2 = 2;
-            calculation_type const c3 = 3;
-
-            if (geometry::math::equals(S, c0) || geometry::math::equals(C, c0))
-            {
-                return c0;
-            }
-
-            calculation_type const omega = atan(sqrt(S / C));
-            calculation_type const r3 = c3 * sqrt(S * C) / omega; // not sure if this is r or greek nu
-            calculation_type const D = c2 * omega * m_ellipsoid.a();
-            calculation_type const H1 = (r3 - c1) / (c2 * C);
-            calculation_type const H2 = (r3 + c1) / (c2 * S);
-            calculation_type const f = m_ellipsoid.f();
+        CT const omega = atan(sqrt(S / C));
+        CT const r3 = c3 * sqrt(S * C) / omega; // not sure if this is r or greek nu
+        CT const D = c2 * omega * m_ellipsoid.a();
+        CT const H1 = (r3 - c1) / (c2 * C);
+        CT const H2 = (r3 + c1) / (c2 * S);
+        CT const f = m_ellipsoid.f();
 
-            return D * (c1 + f * H1 * sinF2 * cosG2 - f * H2 * cosF2 * sinG2);
-        }
+        return D * (c1 + f * H1 * sinF2 * cosG2 - f * H2 * cosF2 * sinG2);
+    }
 };
 
 
@@ -147,57 +153,41 @@
 namespace services
 {
 
-template <typename Point1, typename Point2>
-struct tag<strategy::distance::andoyer<Point1, Point2> >
+template <typename RadiusType, typename CalculationType>
+struct tag<strategy::distance::andoyer<RadiusType, CalculationType> >
 {
     typedef strategy_tag_distance_point_point type;
 };
 
 
-template <typename Point1, typename Point2>
-struct return_type<strategy::distance::andoyer<Point1, Point2> >
-{
-    typedef typename strategy::distance::andoyer<Point1, Point2>::calculation_type type;
-};
-
-
-template <typename Point1, typename Point2, typename P1, typename P2>
-struct similar_type<andoyer<Point1, Point2>, P1, P2>
-{
-    typedef andoyer<P1, P2> type;
-};
-
+template <typename RadiusType, typename CalculationType, typename P1, typename P2>
+struct return_type<strategy::distance::andoyer<RadiusType, CalculationType>, P1, P2>
+    : andoyer<RadiusType, CalculationType>::template calculation_type<P1, P2>
+{};
 
-template <typename Point1, typename Point2, typename P1, typename P2>
-struct get_similar<andoyer<Point1, Point2>, P1, P2>
-{
-    static inline andoyer<P1, P2> apply(andoyer<Point1, Point2> const& input)
-    {
-        return andoyer<P1, P2>(input.ellipsoid());
-    }
-};
 
-template <typename Point1, typename Point2>
-struct comparable_type<andoyer<Point1, Point2> >
+template <typename RadiusType, typename CalculationType>
+struct comparable_type<andoyer<RadiusType, CalculationType> >
 {
-    typedef andoyer<Point1, Point2> type;
+    typedef andoyer<RadiusType, CalculationType> type;
 };
 
 
-template <typename Point1, typename Point2>
-struct get_comparable<andoyer<Point1, Point2> >
+template <typename RadiusType, typename CalculationType>
+struct get_comparable<andoyer<RadiusType, CalculationType> >
 {
-    static inline andoyer<Point1, Point2> apply(andoyer<Point1, Point2> const& input)
+    static inline andoyer<RadiusType, CalculationType> apply(andoyer<RadiusType, CalculationType> const& input)
     {
         return input;
     }
 };
 
-template <typename Point1, typename Point2>
-struct result_from_distance<andoyer<Point1, Point2> >
+template <typename RadiusType, typename CalculationType, typename P1, typename P2>
+struct result_from_distance<andoyer<RadiusType, CalculationType>, P1, P2>
 {
     template <typename T>
-    static inline typename return_type<andoyer<Point1, Point2> >::type apply(andoyer<Point1, Point2> const& , T const& value)
+    static inline typename return_type<andoyer<RadiusType, CalculationType>, P1, P2>::type 
+        apply(andoyer<RadiusType, CalculationType> const& , T const& value)
     {
         return value;
     }
@@ -207,7 +197,7 @@
 template <typename Point1, typename Point2>
 struct default_strategy<point_tag, Point1, Point2, geographic_tag, geographic_tag>
 {
-    typedef strategy::distance::andoyer<Point1, Point2> type;
+    typedef strategy::distance::andoyer<double> type;
 };
 
 
Modified: trunk/libs/geometry/extensions/test/gis/latlong/andoyer.cpp
==============================================================================
--- trunk/libs/geometry/extensions/test/gis/latlong/andoyer.cpp	Wed Jul 17 05:48:43 2013	(r85056)
+++ trunk/libs/geometry/extensions/test/gis/latlong/andoyer.cpp	2013-07-17 09:32:12 EDT (Wed, 17 Jul 2013)	(r85057)
@@ -33,12 +33,22 @@
 template <typename P1, typename P2>
 void test_andoyer(double lon1, double lat1, double lon2, double lat2, double expected_km)
 {
-    typedef bg::strategy::distance::andoyer<P1, P2> andoyer_type;
-
-    BOOST_CONCEPT_ASSERT( (bg::concept::PointDistanceStrategy<andoyer_type>) );
+    // Set radius type, but for integer coordinates we want to have floating point radius type
+    typedef typename bg::promote_floating_point
+        <
+            typename bg::coordinate_type<P1>::type
+        >::type rtype;
+
+    typedef bg::strategy::distance::andoyer<rtype> andoyer_type;
+
+    BOOST_CONCEPT_ASSERT
+        ( 
+            (bg::concept::PointDistanceStrategy<andoyer_type, P1, P2>) 
+        );
 
     andoyer_type andoyer;
-    typedef typename bg::strategy::distance::services::return_type<andoyer_type>::type return_type;
+    typedef typename bg::strategy::distance
+        ::services::return_type<andoyer_type, P1, P2>::type return_type;
 
 
     P1 p1, p2;