]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/geometry/strategies/spherical/distance_cross_track_point_box.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / geometry / strategies / spherical / distance_cross_track_point_box.hpp
index ee805c36d1287c4b699877a518fc0820b7d92af0..9c8e7f1a3e1dddbd7db14befb5e5810f602bd709 100644 (file)
@@ -4,11 +4,12 @@
 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
 
-// This file was modified by Oracle on 2014, 2015.
-// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014-2017.
+// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
 
-// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
 
 // Use, modification and distribution is subject to the Boost Software License,
 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -42,92 +43,46 @@ namespace boost { namespace geometry
 namespace strategy { namespace distance
 {
 
-
-/*!
-\brief Strategy functor for distance point to box calculation
-\ingroup strategies
-\details Class which calculates the distance of a point to a box, for
-points and boxes on a sphere or globe
-\tparam CalculationType \tparam_calculation
-\tparam Strategy underlying point-segment distance strategy, defaults
-to cross track
-
-\qbk{
-[heading See also]
-[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
-}
-
-*/
-template
-<
-    typename CalculationType = void,
-    typename Strategy = cross_track<CalculationType>
->
-class cross_track_point_box
+namespace details
 {
-public:
-    template <typename Point, typename Box>
-    struct return_type
-        : services::return_type<Strategy, Point, typename point_type<Box>::type>
-    {};
-
-    typedef typename Strategy::radius_type radius_type;
-
-    inline cross_track_point_box()
-    {}
-
-    explicit inline cross_track_point_box(typename Strategy::radius_type const& r)
-        : m_ps_strategy(r)
-    {}
-
-    inline cross_track_point_box(Strategy const& s)
-        : m_ps_strategy(s)
-    {}
 
+template <typename ReturnType>
+class cross_track_point_box_generic
+{
+public :
 
-    // It might be useful in the future
-    // to overload constructor with strategy info.
-    // crosstrack(...) {}
-
-    template <typename Point, typename Box>
-    inline typename return_type<Point, Box>::type
-    apply(Point const& point, Box const& box) const
+    template
+    <
+            typename Point,
+            typename Box,
+            typename Strategy
+    >
+    ReturnType static inline apply (Point const& point,
+                                    Box const& box,
+                                    Strategy ps_strategy)
     {
-#if !defined(BOOST_MSVC)
-        BOOST_CONCEPT_ASSERT
-            (
-                (concepts::PointSegmentDistanceStrategy
-                    <
-                        Strategy, Point, typename point_type<Box>::type
-                    >)
-            );
-#endif
-
         // this method assumes that the coordinates of the point and
         // the box are normalized
 
-        typedef typename return_type<Point, Box>::type return_type;
         typedef typename point_type<Box>::type box_point_type;
 
-        // TODO: This strategy as well as other cross-track strategies
-        // and therefore e.g. spherical within(Point, Box) may not work
-        // properly for a Box degenerated to a Segment or Point
-
         box_point_type bottom_left, bottom_right, top_left, top_right;
         geometry::detail::assign_box_corners(box,
                                              bottom_left, bottom_right,
                                              top_left, top_right);
 
-        return_type const plon = geometry::get_as_radian<0>(point);
-        return_type const plat = geometry::get_as_radian<1>(point);
+        ReturnType const plon = geometry::get_as_radian<0>(point);
+        ReturnType const plat = geometry::get_as_radian<1>(point);
 
-        return_type const lon_min = geometry::get_as_radian<0>(bottom_left);
-        return_type const lat_min = geometry::get_as_radian<1>(bottom_left);
-        return_type const lon_max = geometry::get_as_radian<0>(top_right);
-        return_type const lat_max = geometry::get_as_radian<1>(top_right);
+        ReturnType const lon_min = geometry::get_as_radian<0>(bottom_left);
+        ReturnType const lat_min = geometry::get_as_radian<1>(bottom_left);
+        ReturnType const lon_max = geometry::get_as_radian<0>(top_right);
+        ReturnType const lat_max = geometry::get_as_radian<1>(top_right);
 
-        return_type const pi = math::pi<return_type>();
-        return_type const two_pi = math::two_pi<return_type>();
+        ReturnType const pi = math::pi<ReturnType>();
+        ReturnType const two_pi = math::two_pi<ReturnType>();
+
+        typedef typename point_type<Box>::type box_point_type;
 
         // First check if the point is within the band defined by the
         // minimum and maximum longitude of the box; if yes, determine
@@ -142,22 +97,22 @@ public:
         {
             if (plat > lat_max)
             {
-                return services::result_from_distance
-                    <
-                        Strategy, Point, box_point_type
-                    >::apply(m_ps_strategy, radius() * (plat - lat_max));
+                return geometry::strategy::distance::services::result_from_distance
+                        <
+                            Strategy, Point, box_point_type
+                        >::apply(ps_strategy, ps_strategy.get_distance_strategy().meridian(plat, lat_max));
             }
             else if (plat < lat_min)
             {
-                return services::result_from_distance
-                    <
-                        Strategy, Point, box_point_type
-                    >::apply(m_ps_strategy, radius() * (lat_min - plat));
+                return geometry::strategy::distance::services::result_from_distance
+                        <
+                            Strategy, Point, box_point_type
+                        >::apply(ps_strategy, ps_strategy.get_distance_strategy().meridian(lat_min, plat));
             }
             else
             {
                 BOOST_GEOMETRY_ASSERT(plat >= lat_min && plat <= lat_max);
-                return return_type(0);
+                return ReturnType(0);
             }
         }
 
@@ -169,14 +124,14 @@ public:
         // (1) is midway between the meridians of the left and right
         //     meridians of the box, and
         // (2) does not intersect the box
-        return_type const two = 2.0;
+        ReturnType const two = 2.0;
         bool use_left_segment;
         if (lon_max > pi)
         {
             // the box crosses the antimeridian
 
             // midway longitude = lon_min - (lon_min + (lon_max - 2 * pi)) / 2;
-            return_type const lon_midway = (lon_min - lon_max) / two + pi;
+            ReturnType const lon_midway = (lon_min - lon_max) / two + pi;
             BOOST_GEOMETRY_ASSERT(lon_midway >= -pi && lon_midway <= pi);
 
             use_left_segment = plon > lon_midway;
@@ -185,8 +140,8 @@ public:
         {
             // the box does not cross the antimeridian
 
-            return_type const lon_sum = lon_min + lon_max;
-            if (math::equals(lon_sum, return_type(0)))
+            ReturnType const lon_sum = lon_min + lon_max;
+            if (math::equals(lon_sum, ReturnType(0)))
             {
                 // special case: the box is symmetric with respect to
                 // the prime meridian; the midway meridian is the antimeridian
@@ -196,7 +151,7 @@ public:
             else
             {
                 // midway long. = lon_min - (2 * pi - (lon_max - lon_min)) / 2;
-                return_type lon_midway = (lon_min + lon_max) / two - pi;
+                ReturnType lon_midway = (lon_min + lon_max) / two - pi;
 
                 // normalize the midway longitude
                 if (lon_midway > pi)
@@ -212,14 +167,79 @@ public:
                 // if lon_sum is positive the midway meridian is left
                 // of the box, or right of the box otherwise
                 use_left_segment = lon_sum > 0
-                    ? (plon < lon_min && plon >= lon_midway)
-                    : (plon <= lon_max || plon > lon_midway);
+                        ? (plon < lon_min && plon >= lon_midway)
+                        : (plon <= lon_max || plon > lon_midway);
             }
         }
 
         return use_left_segment
-            ? m_ps_strategy.apply(point, bottom_left, top_left)
-            : m_ps_strategy.apply(point, bottom_right, top_right);
+                ? ps_strategy.apply(point, bottom_left, top_left)
+                : ps_strategy.apply(point, bottom_right, top_right);
+    }
+};
+
+}  //namespace details
+
+/*!
+\brief Strategy functor for distance point to box calculation
+\ingroup strategies
+\details Class which calculates the distance of a point to a box, for
+points and boxes on a sphere or globe
+\tparam CalculationType \tparam_calculation
+\tparam Strategy underlying point-segment distance strategy, defaults
+to cross track
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
+}
+*/
+template
+<
+    typename CalculationType = void,
+    typename Strategy = cross_track<CalculationType>
+>
+class cross_track_point_box
+{
+public:
+    template <typename Point, typename Box>
+    struct return_type
+        : services::return_type<Strategy, Point, typename point_type<Box>::type>
+    {};
+
+    typedef typename Strategy::radius_type radius_type;
+
+    inline cross_track_point_box()
+    {}
+
+    explicit inline cross_track_point_box(typename Strategy::radius_type const& r)
+        : m_ps_strategy(r)
+    {}
+
+    inline cross_track_point_box(Strategy const& s)
+        : m_ps_strategy(s)
+    {}
+
+
+    // It might be useful in the future
+    // to overload constructor with strategy info.
+    // crosstrack(...) {}
+
+    template <typename Point, typename Box>
+    inline typename return_type<Point, Box>::type
+    apply(Point const& point, Box const& box) const
+    {
+#if !defined(BOOST_MSVC)
+        BOOST_CONCEPT_ASSERT
+            (
+                (concepts::PointSegmentDistanceStrategy
+                    <
+                        Strategy, Point, typename point_type<Box>::type
+                    >)
+            );
+#endif
+        typedef typename return_type<Point, Box>::type return_type;
+        return details::cross_track_point_box_generic
+                               <return_type>::apply(point, box, m_ps_strategy);
     }
 
     inline typename Strategy::radius_type radius() const