]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/geometry/policies/robustness/get_rescale_policy.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / geometry / policies / robustness / get_rescale_policy.hpp
index daf32d3057b5bc4c6302c0c73ee6836083140247..4fa04fe41146dac864b7c2a86e049c43d8cf0847 100644 (file)
@@ -5,10 +5,11 @@
 // Copyright (c) 2014-2015 Mateusz Loskot, London, UK.
 // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
 
-// This file was modified by Oracle on 2015.
-// Modifications copyright (c) 2015, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2015, 2019.
+// Modifications copyright (c) 2015, 2019, Oracle and/or its affiliates.
 
 // 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
@@ -25,6 +26,7 @@
 #include <boost/type_traits/is_same.hpp>
 
 #include <boost/geometry/core/assert.hpp>
+#include <boost/geometry/core/config.hpp>
 #include <boost/geometry/core/tag_cast.hpp>
 
 #include <boost/geometry/algorithms/envelope.hpp>
@@ -90,29 +92,45 @@ inline void scale_box_to_integer_range(Box const& box,
     assign_values(min_robust_point, min_coordinate, min_coordinate);
 }
 
-template <typename Point, typename RobustPoint, typename Geometry, typename Factor>
+template
+<
+    typename Point, typename RobustPoint, typename Geometry,
+    typename Factor, typename EnvelopeStrategy
+>
 static inline void init_rescale_policy(Geometry const& geometry,
         Point& min_point,
         RobustPoint& min_robust_point,
-        Factor& factor)
+        Factor& factor,
+        EnvelopeStrategy const& strategy)
 {
     if (geometry::is_empty(geometry))
     {
         return;
     }
 
-    // Get bounding boxes
-    model::box<Point> env = geometry::return_envelope<model::box<Point> >(geometry);
+    // Get bounding box
+    model::box<Point> env = geometry::return_envelope
+                                <
+                                    model::box<Point>
+                                >(geometry, strategy);
 
     scale_box_to_integer_range(env, min_point, min_robust_point, factor);
 }
 
-template <typename Point, typename RobustPoint, typename Geometry1, typename Geometry2, typename Factor>
+// NOTE: Actually it should take 2 separate strategies, one for each geometry
+// in case one of them was e.g. a Box
+template
+<
+    typename Point, typename RobustPoint, typename Geometry1, typename Geometry2,
+    typename Factor, typename EnvelopeStrategy1, typename EnvelopeStrategy2
+>
 static inline void init_rescale_policy(Geometry1 const& geometry1,
         Geometry2 const& geometry2,
         Point& min_point,
         RobustPoint& min_robust_point,
-        Factor& factor)
+        Factor& factor,
+        EnvelopeStrategy1 const& strategy1,
+        EnvelopeStrategy2 const& strategy2)
 {
     // Get bounding boxes (when at least one of the geometries is not empty)
     bool const is_empty1 = geometry::is_empty(geometry1);
@@ -125,11 +143,11 @@ static inline void init_rescale_policy(Geometry1 const& geometry1,
     model::box<Point> env;
     if (is_empty1)
     {
-        geometry::envelope(geometry2, env);
+        geometry::envelope(geometry2, env, strategy2);
     }
     else if (is_empty2)
     {
-        geometry::envelope(geometry1, env);
+        geometry::envelope(geometry1, env, strategy1);
     }
     else
     {
@@ -137,12 +155,12 @@ static inline void init_rescale_policy(Geometry1 const& geometry1,
         // optimal MBR when then two geometries are in the spherical
         // equatorial or geographic coordinate systems.
         // TODO: implement envelope for two (or possibly more geometries)
-        geometry::envelope(geometry1, env);
+        geometry::envelope(geometry1, env, strategy1);
         model::box<Point> env2 = geometry::return_envelope
             <
                 model::box<Point>
-            >(geometry2);
-        geometry::expand(env, env2);
+            >(geometry2, strategy2);
+        geometry::expand(env, env2, strategy1.get_box_expand_strategy());
     }
 
     scale_box_to_integer_range(env, min_point, min_robust_point, factor);
@@ -180,8 +198,9 @@ struct rescale_policy_type<Point, true>
 template <typename Policy>
 struct get_rescale_policy
 {
-    template <typename Geometry>
-    static inline Policy apply(Geometry const& geometry)
+    template <typename Geometry, typename EnvelopeStrategy>
+    static inline Policy apply(Geometry const& geometry,
+                               EnvelopeStrategy const& strategy)
     {
         typedef typename point_type<Geometry>::type point_type;
         typedef typename geometry::coordinate_type<Geometry>::type coordinate_type;
@@ -196,13 +215,16 @@ struct get_rescale_policy
         point_type min_point;
         robust_point_type min_robust_point;
         factor_type factor;
-        init_rescale_policy(geometry, min_point, min_robust_point, factor);
+        init_rescale_policy(geometry, min_point, min_robust_point,
+                            factor, strategy);
 
         return Policy(min_point, min_robust_point, factor);
     }
 
-    template <typename Geometry1, typename Geometry2>
-    static inline Policy apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+    template <typename Geometry1, typename Geometry2, typename EnvelopeStrategy1, typename EnvelopeStrategy2>
+    static inline Policy apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
+                               EnvelopeStrategy1 const& strategy1,
+                               EnvelopeStrategy2 const& strategy2)
     {
         typedef typename point_type<Geometry1>::type point_type;
         typedef typename geometry::coordinate_type<Geometry1>::type coordinate_type;
@@ -217,7 +239,8 @@ struct get_rescale_policy
         point_type min_point;
         robust_point_type min_robust_point;
         factor_type factor;
-        init_rescale_policy(geometry1, geometry2, min_point, min_robust_point, factor);
+        init_rescale_policy(geometry1, geometry2, min_point, min_robust_point,
+                            factor, strategy1, strategy2);
 
         return Policy(min_point, min_robust_point, factor);
     }
@@ -227,14 +250,15 @@ struct get_rescale_policy
 template <>
 struct get_rescale_policy<no_rescale_policy>
 {
-    template <typename Geometry>
-    static inline no_rescale_policy apply(Geometry const& )
+    template <typename Geometry, typename EnvelopeStrategy>
+    static inline no_rescale_policy apply(Geometry const& , EnvelopeStrategy const&)
     {
         return no_rescale_policy();
     }
 
-    template <typename Geometry1, typename Geometry2>
-    static inline no_rescale_policy apply(Geometry1 const& , Geometry2 const& )
+    template <typename Geometry1, typename Geometry2, typename EnvelopeStrategy1, typename EnvelopeStrategy2>
+    static inline no_rescale_policy apply(Geometry1 const& , Geometry2 const& ,
+                                          EnvelopeStrategy1 const& , EnvelopeStrategy2 const& )
     {
         return no_rescale_policy();
     }
@@ -244,14 +268,16 @@ struct get_rescale_policy<no_rescale_policy>
 }} // namespace detail::get_rescale_policy
 #endif // DOXYGEN_NO_DETAIL
 
-template<typename Point>
+template
+<
+    typename Point,
+    typename CSTag = typename geometry::cs_tag<Point>::type
+>
 struct rescale_policy_type
     : public detail::get_rescale_policy::rescale_policy_type
     <
         Point,
-#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
-        false
-#else
+#if defined(BOOST_GEOMETRY_USE_RESCALING)
         boost::is_floating_point
             <
                 typename geometry::coordinate_type<Point>::type
@@ -259,9 +285,11 @@ struct rescale_policy_type
         &&
         boost::is_same
             <
-                typename geometry::coordinate_system<Point>::type,
-                geometry::cs::cartesian
+                CSTag,
+                geometry::cartesian_tag
             >::value
+#else
+        false
 #endif
     >
 {
@@ -282,6 +310,7 @@ template
 <
     typename Geometry1,
     typename Geometry2,
+    typename CSTag = typename geometry::cs_tag<Geometry1>::type,
     typename Tag1 = typename tag_cast
     <
         typename tag<Geometry1>::type,
@@ -312,26 +341,189 @@ struct rescale_overlay_policy_type
 template
 <
     typename Geometry1,
-    typename Geometry2
+    typename Geometry2,
+    typename CSTag
 >
-struct rescale_overlay_policy_type<Geometry1, Geometry2, areal_tag, areal_tag>
+struct rescale_overlay_policy_type<Geometry1, Geometry2, CSTag, areal_tag, areal_tag>
     : public rescale_policy_type
         <
-            typename geometry::point_type<Geometry1>::type
+            typename geometry::point_type<Geometry1>::type,
+            CSTag
         >
 {};
 
 
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace get_rescale_policy
+{
+
+
+// get envelope strategy compatible with relate strategy based on geometry tag
+// and strategy cs_tag
+template
+<
+    typename Geometry,
+    typename Strategy,
+    typename Tag = typename geometry::tag<Geometry>::type,
+    typename CSTag = typename Strategy::cs_tag
+>
+struct get_envelope_strategy
+{
+    typedef typename Strategy::envelope_strategy_type type;
+
+    static inline type apply(Strategy const& strategy)
+    {
+        return strategy.get_envelope_strategy();
+    }
+};
+
+template <typename Geometry, typename Strategy, typename CSTag>
+struct get_envelope_strategy<Geometry, Strategy, box_tag, CSTag>
+{
+    typedef typename Strategy::envelope_box_strategy_type type;
+
+    static inline type apply(Strategy const& )
+    {
+        return type();
+    }
+};
+
+// NOTE: within::xxx_point_point shouldn't have a getter for envelope strategy
+// so dispatch by CStag. In the future strategies should probably be redesigned.
+template <typename Geometry, typename Strategy>
+struct get_envelope_strategy<Geometry, Strategy, point_tag, cartesian_tag>
+{
+    typedef strategy::envelope::cartesian_point type;
+
+    static inline type apply(Strategy const& )
+    {
+        return type();
+    }
+};
+template <typename Geometry, typename Strategy>
+struct get_envelope_strategy<Geometry, Strategy, point_tag, spherical_tag>
+{
+    typedef strategy::envelope::spherical_point type;
+
+    static inline type apply(Strategy const& )
+    {
+        return type();
+    }
+};
+
+template <typename Geometry, typename Strategy>
+struct get_envelope_strategy<Geometry, Strategy, multi_point_tag, cartesian_tag>
+{
+    typedef strategy::envelope::cartesian_point type;
+
+    static inline type apply(Strategy const& )
+    {
+        return type();
+    }
+};
+template <typename Geometry, typename Strategy>
+struct get_envelope_strategy<Geometry, Strategy, multi_point_tag, spherical_tag>
+{
+    typedef strategy::envelope::spherical_point type;
+
+    static inline type apply(Strategy const& )
+    {
+        return type();
+    }
+};
+
+
+// utility for backward-compatibility either treating the argument as geometry
+// or envelope strategy for get_rescale_policy
+template
+<
+    typename Geometry2OrStrategy,
+    typename Tag = typename geometry::tag<Geometry2OrStrategy>::type
+>
+struct get_rescale_policy_geometry_or_strategy
+{
+    template <typename Policy, typename Geometry>
+    static inline Policy apply(Geometry const& geometry, Geometry2OrStrategy const& geometry2)
+    {
+        typename geometry::strategy::envelope::services::default_strategy
+            <
+                typename geometry::tag<Geometry>::type,
+                typename geometry::cs_tag<Geometry>::type
+            >::type strategy1;
+        typename geometry::strategy::envelope::services::default_strategy
+            <
+                typename geometry::tag<Geometry2OrStrategy>::type,
+                typename geometry::cs_tag<Geometry2OrStrategy>::type
+            >::type strategy2;
+
+        return detail::get_rescale_policy::get_rescale_policy
+            <
+                Policy
+            >::apply(geometry, geometry2, strategy1, strategy2);
+    }
+};
+
+template <typename Strategy>
+struct get_rescale_policy_geometry_or_strategy<Strategy, void>
+{
+    template <typename Policy, typename Geometry>
+    static inline Policy apply(Geometry const& geometry, Strategy const& strategy)
+    {
+        return detail::get_rescale_policy::get_rescale_policy
+            <
+                Policy
+            >::apply(geometry,
+                     get_envelope_strategy
+                        <
+                            Geometry, Strategy
+                        >::apply(strategy));
+    }
+};
+
+
+}} // namespace detail::get_rescale_policy
+#endif // DOXYGEN_NO_DETAIL
+
+
 template <typename Policy, typename Geometry>
 inline Policy get_rescale_policy(Geometry const& geometry)
 {
-    return detail::get_rescale_policy::get_rescale_policy<Policy>::apply(geometry);
+    typename geometry::strategy::envelope::services::default_strategy
+        <
+            typename geometry::tag<Geometry>::type,
+            typename geometry::cs_tag<Geometry>::type
+        >::type strategy;
+
+    return detail::get_rescale_policy::get_rescale_policy<Policy>::apply(geometry, strategy);
 }
 
-template <typename Policy, typename Geometry1, typename Geometry2>
-inline Policy get_rescale_policy(Geometry1 const& geometry1, Geometry2 const& geometry2)
+template <typename Policy, typename Geometry, typename Geometry2OrStrategy>
+inline Policy get_rescale_policy(Geometry const& geometry, Geometry2OrStrategy const& geometry2_or_strategy)
 {
-    return detail::get_rescale_policy::get_rescale_policy<Policy>::apply(geometry1, geometry2);
+    // if the second argument is a geometry use default strategy
+    // otherwise assume it's envelope strategy for the first argument
+    return detail::get_rescale_policy::get_rescale_policy_geometry_or_strategy
+        <
+            Geometry2OrStrategy
+        > ::template apply<Policy, Geometry>(geometry, geometry2_or_strategy);
+}
+
+template <typename Policy, typename Geometry1, typename Geometry2, typename IntersectionStrategy>
+inline Policy get_rescale_policy(Geometry1 const& geometry1, Geometry2 const& geometry2,
+                                 IntersectionStrategy const& strategy)
+{
+    return detail::get_rescale_policy::get_rescale_policy
+            <
+                Policy
+            >::apply(geometry1, geometry2,
+                     detail::get_rescale_policy::get_envelope_strategy
+                        <
+                            Geometry1, IntersectionStrategy
+                        >::apply(strategy),
+                     detail::get_rescale_policy::get_envelope_strategy
+                        <
+                            Geometry2, IntersectionStrategy
+                        >::apply(strategy));
 }