summaryrefslogtreecommitdiff
path: root/boost/geometry/policies/robustness/get_rescale_policy.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/policies/robustness/get_rescale_policy.hpp')
-rw-r--r--boost/geometry/policies/robustness/get_rescale_policy.hpp257
1 files changed, 224 insertions, 33 deletions
diff --git a/boost/geometry/policies/robustness/get_rescale_policy.hpp b/boost/geometry/policies/robustness/get_rescale_policy.hpp
index 9bb3f885a7..4fa04fe411 100644
--- a/boost/geometry/policies/robustness/get_rescale_policy.hpp
+++ b/boost/geometry/policies/robustness/get_rescale_policy.hpp
@@ -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
@@ -91,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);
@@ -126,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
{
@@ -138,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);
@@ -181,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;
@@ -197,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;
@@ -218,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);
}
@@ -228,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();
}
@@ -245,7 +268,11 @@ 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
<
@@ -258,8 +285,8 @@ struct rescale_policy_type
&&
boost::is_same
<
- typename geometry::coordinate_system<Point>::type,
- geometry::cs::cartesian
+ CSTag,
+ geometry::cartesian_tag
>::value
#else
false
@@ -283,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,
@@ -313,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 Geometry, typename Geometry2OrStrategy>
+inline Policy get_rescale_policy(Geometry const& geometry, Geometry2OrStrategy const& geometry2_or_strategy)
+{
+ // 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>
-inline Policy get_rescale_policy(Geometry1 const& geometry1, Geometry2 const& geometry2)
+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);
+ 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));
}