diff options
Diffstat (limited to 'boost/geometry/policies/robustness/get_rescale_policy.hpp')
-rw-r--r-- | boost/geometry/policies/robustness/get_rescale_policy.hpp | 257 |
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)); } |