Boost logo

Boost-Commit :

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;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk