]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / strategies / agnostic / point_in_box_by_side.hpp
index f87656dbce90dc0ff7c2950d187b717544f53286..448ae4393674a7b04b040aee6186fe99f9f4310b 100644 (file)
@@ -4,8 +4,8 @@
 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
 
-// This file was modified by Oracle on 2018.
-// Modifications copyright (c) 2018 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2018-2020.
+// Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
 
 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
 
 #include <boost/array.hpp>
 #include <boost/core/ignore_unused.hpp>
+
 #include <boost/geometry/core/access.hpp>
 #include <boost/geometry/core/coordinate_dimension.hpp>
+
 #include <boost/geometry/algorithms/assign.hpp>
-#include <boost/geometry/strategies/covered_by.hpp>
+
 #include <boost/geometry/strategies/side.hpp>
+
+#include <boost/geometry/strategies/covered_by.hpp>
 #include <boost/geometry/strategies/within.hpp>
+#include <boost/geometry/strategies/geographic/side.hpp>
+#include <boost/geometry/strategies/spherical/ssf.hpp>
 
 
 namespace boost { namespace geometry { namespace strategy
@@ -34,6 +40,10 @@ namespace boost { namespace geometry { namespace strategy
 namespace within
 {
 
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
 struct decide_within
 {
     static inline bool apply(int side, bool& result)
@@ -65,45 +75,186 @@ struct decide_covered_by
 // This strategy is not suitable for boxes in non-cartesian CSes having edges
 // longer than 180deg because e.g. the SSF formula picks the side of the closer
 // longitude, so for long edges the side is the opposite.
-template <typename Decide = decide_within>
-struct point_in_box_by_side
+// Actually it is not suitable for shorter edges either because the edges of
+// boxes are defined by meridians and parallels, not great circles or geodesics.
+template <typename Decide, typename Point, typename Box, typename Strategy>
+inline bool point_in_box_by_side(Point const& point, Box const& box,
+                                 Strategy const& strategy)
+{
+    boost::ignore_unused(strategy);
+
+    // Create (counterclockwise) array of points, the fifth one closes it
+    // Every point should be on the LEFT side (=1), or ON the border (=0),
+    // So >= 1 or >= 0
+    boost::array<typename point_type<Box>::type, 5> bp;
+    geometry::detail::assign_box_corners_oriented<true>(box, bp);
+    bp[4] = bp[0];
+
+    bool result = true;
+    for (int i = 1; i < 5; i++)
+    {
+        int const side = strategy.apply(point, bp[i - 1], bp[i]);
+        if (! Decide::apply(side, result))
+        {
+            return result;
+        }
+    }
+
+    return result;
+}
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+// There should probably be another category of geometry different than box,
+// e.g. rectangle or convex_ring. This strategy should probably be an
+// algorithm calling side strategy.
+
+template <typename CalculationType = void>
+struct cartesian_point_box_by_side
+{
+    template <typename Point, typename Box>
+    static inline bool apply(Point const& point, Box const& box)
+    {
+        using side_strategy_type
+            = typename strategy::side::services::default_strategy
+                <cartesian_tag, CalculationType>::type;
+
+        return within::detail::point_in_box_by_side
+            <
+                within::detail::decide_within
+            >(point, box, side_strategy_type());
+    }
+};
+
+template <typename CalculationType = void>
+struct spherical_point_box_by_side
 {
     template <typename Point, typename Box>
     static inline bool apply(Point const& point, Box const& box)
     {
-        typedef typename strategy::side::services::default_strategy
+        return within::detail::point_in_box_by_side
             <
-                typename cs_tag<Box>::type
-            >::type side_strategy_type;
+                within::detail::decide_within
+            >(point, box,
+              strategy::side::spherical_side_formula<CalculationType>());
+    }
+};
 
-        // Create (counterclockwise) array of points, the fifth one closes it
-        // Every point should be on the LEFT side (=1), or ON the border (=0),
-        // So >= 1 or >= 0
-        boost::array<typename point_type<Box>::type, 5> bp;
-        geometry::detail::assign_box_corners_oriented<true>(box, bp);
-        bp[4] = bp[0];
+template
+<
+    typename FormulaPolicy = strategy::andoyer,
+    typename Spheroid = srs::spheroid<double>,
+    typename CalculationType = void
+>
+struct geographic_point_box_by_side
+{
+    geographic_point_box_by_side() = default;
 
-        bool result = true;
-        side_strategy_type strategy;
-        boost::ignore_unused(strategy);
+    explicit geographic_point_box_by_side(Spheroid const& spheroid)
+        : m_side(spheroid)
+    {}
 
-        for (int i = 1; i < 5; i++)
-        {
-            int const side = strategy.apply(point, bp[i - 1], bp[i]);
-            if (! Decide::apply(side, result))
-            {
-                return result;
-            }
-        }
+    template <typename Point, typename Box>
+    bool apply(Point const& point, Box const& box) const
+    {
+        return within::detail::point_in_box_by_side
+            <
+                within::detail::decide_within
+            >(point, box, m_side);
+    }
 
-        return result;
+    Spheroid const& model() const
+    {
+        return m_side.model();
     }
+
+private:
+    strategy::side::geographic
+        <
+            FormulaPolicy, Spheroid, CalculationType
+        > m_side;
 };
 
 
 } // namespace within
 
 
+namespace covered_by
+{
+
+
+template <typename CalculationType = void>
+struct cartesian_point_box_by_side
+{
+    template <typename Point, typename Box>
+    static bool apply(Point const& point, Box const& box)
+    {
+        using side_strategy_type
+            = typename strategy::side::services::default_strategy
+                <cartesian_tag, CalculationType>::type;
+        return within::detail::point_in_box_by_side
+            <
+                within::detail::decide_covered_by
+            >(point, box, side_strategy_type());
+    }
+};
+
+template <typename CalculationType = void>
+struct spherical_point_box_by_side
+{
+    template <typename Point, typename Box>
+    static bool apply(Point const& point, Box const& box)
+    {
+        return within::detail::point_in_box_by_side
+            <
+                within::detail::decide_covered_by
+            >(point, box,
+              strategy::side::spherical_side_formula<CalculationType>());
+    }
+};
+
+template
+<
+    typename FormulaPolicy = strategy::andoyer,
+    typename Spheroid = srs::spheroid<double>,
+    typename CalculationType = void
+>
+struct geographic_point_box_by_side
+{
+    geographic_point_box_by_side() = default;
+
+    explicit geographic_point_box_by_side(Spheroid const& spheroid)
+        : m_side(spheroid)
+    {}
+
+    template <typename Point, typename Box>
+    bool apply(Point const& point, Box const& box) const
+    {
+        return within::detail::point_in_box_by_side
+            <
+                within::detail::decide_covered_by
+            >(point, box, m_side);
+    }
+
+    Spheroid const& model() const
+    {
+        return m_side.model();
+    }
+
+private:
+    strategy::side::geographic
+        <
+            FormulaPolicy, Spheroid, CalculationType
+        > m_side;
+};
+
+
+}
+
+
 }}} // namespace boost::geometry::strategy