Chris@102: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@102: Chris@102: // Copyright (c) 2014-2015 Barend Gehrels, Amsterdam, the Netherlands. Chris@102: // Copyright (c) 2014-2015 Bruno Lalande, Paris, France. Chris@102: // Copyright (c) 2014-2015 Mateusz Loskot, London, UK. Chris@102: // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland. Chris@102: Chris@102: // This file was modified by Oracle on 2015. Chris@102: // Modifications copyright (c) 2015, Oracle and/or its affiliates. Chris@102: Chris@102: // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle Chris@102: Chris@102: // Use, modification and distribution is subject to the Boost Software License, Chris@102: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@102: // http://www.boost.org/LICENSE_1_0.txt) Chris@102: Chris@102: #ifndef BOOST_GEOMETRY_POLICIES_ROBUSTNESS_GET_RESCALE_POLICY_HPP Chris@102: #define BOOST_GEOMETRY_POLICIES_ROBUSTNESS_GET_RESCALE_POLICY_HPP Chris@102: Chris@102: Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include Chris@102: Chris@102: namespace boost { namespace geometry Chris@102: { Chris@102: Chris@102: #ifndef DOXYGEN_NO_DETAIL Chris@102: namespace detail { namespace get_rescale_policy Chris@102: { Chris@102: Chris@102: template Chris@102: < Chris@102: typename Box, Chris@102: typename Point, Chris@102: typename RobustPoint, Chris@102: typename Factor Chris@102: > Chris@102: inline void scale_box_to_integer_range(Box const& box, Chris@102: Point& min_point, Chris@102: RobustPoint& min_robust_point, Chris@102: Factor& factor) Chris@102: { Chris@102: // Scale box to integer-range Chris@102: typedef typename promote_floating_point Chris@102: < Chris@102: typename geometry::coordinate_type::type Chris@102: >::type num_type; Chris@102: num_type const diff = boost::numeric_cast(detail::get_max_size(box)); Chris@102: num_type const range = 10000000.0; // Define a large range to get precise integer coordinates Chris@102: num_type const half = 0.5; Chris@102: factor = math::equals(diff, num_type()) || diff >= range ? 1 Chris@102: : boost::numeric_cast( Chris@102: boost::numeric_cast(half + range / diff)); Chris@102: Chris@102: BOOST_ASSERT(factor >= 1); Chris@102: Chris@102: // Assign input/output minimal points Chris@102: detail::assign_point_from_index<0>(box, min_point); Chris@102: num_type const two = 2; Chris@102: boost::long_long_type const min_coordinate Chris@102: = boost::numeric_cast(-range / two); Chris@102: assign_values(min_robust_point, min_coordinate, min_coordinate); Chris@102: } Chris@102: Chris@102: template Chris@102: static inline void init_rescale_policy(Geometry const& geometry, Chris@102: Point& min_point, Chris@102: RobustPoint& min_robust_point, Chris@102: Factor& factor) Chris@102: { Chris@102: // Get bounding boxes Chris@102: model::box env = geometry::return_envelope >(geometry); Chris@102: Chris@102: scale_box_to_integer_range(env, min_point, min_robust_point, factor); Chris@102: } Chris@102: Chris@102: template Chris@102: static inline void init_rescale_policy(Geometry1 const& geometry1, Chris@102: Geometry2 const& geometry2, Chris@102: Point& min_point, Chris@102: RobustPoint& min_robust_point, Chris@102: Factor& factor) Chris@102: { Chris@102: // Get bounding boxes Chris@102: model::box env = geometry::return_envelope >(geometry1); Chris@102: model::box env2 = geometry::return_envelope >(geometry2); Chris@102: geometry::expand(env, env2); Chris@102: Chris@102: scale_box_to_integer_range(env, min_point, min_robust_point, factor); Chris@102: } Chris@102: Chris@102: Chris@102: template Chris@102: < Chris@102: typename Point, Chris@102: bool IsFloatingPoint Chris@102: > Chris@102: struct rescale_policy_type Chris@102: { Chris@102: typedef no_rescale_policy type; Chris@102: }; Chris@102: Chris@102: // We rescale only all FP types Chris@102: template Chris@102: < Chris@102: typename Point Chris@102: > Chris@102: struct rescale_policy_type Chris@102: { Chris@102: typedef typename geometry::coordinate_type::type coordinate_type; Chris@102: typedef model::point Chris@102: < Chris@102: typename detail::robust_type::type, Chris@102: geometry::dimension::value, Chris@102: typename geometry::coordinate_system::type Chris@102: > robust_point_type; Chris@102: typedef typename promote_floating_point::type factor_type; Chris@102: typedef detail::robust_policy type; Chris@102: }; Chris@102: Chris@102: template Chris@102: struct get_rescale_policy Chris@102: { Chris@102: template Chris@102: static inline Policy apply(Geometry const& geometry) Chris@102: { Chris@102: typedef typename point_type::type point_type; Chris@102: typedef typename geometry::coordinate_type::type coordinate_type; Chris@102: typedef typename promote_floating_point::type factor_type; Chris@102: typedef model::point Chris@102: < Chris@102: typename detail::robust_type::type, Chris@102: geometry::dimension::value, Chris@102: typename geometry::coordinate_system::type Chris@102: > robust_point_type; Chris@102: Chris@102: point_type min_point; Chris@102: robust_point_type min_robust_point; Chris@102: factor_type factor; Chris@102: init_rescale_policy(geometry, min_point, min_robust_point, factor); Chris@102: Chris@102: return Policy(min_point, min_robust_point, factor); Chris@102: } Chris@102: Chris@102: template Chris@102: static inline Policy apply(Geometry1 const& geometry1, Geometry2 const& geometry2) Chris@102: { Chris@102: typedef typename point_type::type point_type; Chris@102: typedef typename geometry::coordinate_type::type coordinate_type; Chris@102: typedef typename promote_floating_point::type factor_type; Chris@102: typedef model::point Chris@102: < Chris@102: typename detail::robust_type::type, Chris@102: geometry::dimension::value, Chris@102: typename geometry::coordinate_system::type Chris@102: > robust_point_type; Chris@102: Chris@102: point_type min_point; Chris@102: robust_point_type min_robust_point; Chris@102: factor_type factor; Chris@102: init_rescale_policy(geometry1, geometry2, min_point, min_robust_point, factor); Chris@102: Chris@102: return Policy(min_point, min_robust_point, factor); Chris@102: } Chris@102: }; Chris@102: Chris@102: // Specialization for no-rescaling Chris@102: template <> Chris@102: struct get_rescale_policy Chris@102: { Chris@102: template Chris@102: static inline no_rescale_policy apply(Geometry const& ) Chris@102: { Chris@102: return no_rescale_policy(); Chris@102: } Chris@102: Chris@102: template Chris@102: static inline no_rescale_policy apply(Geometry1 const& , Geometry2 const& ) Chris@102: { Chris@102: return no_rescale_policy(); Chris@102: } Chris@102: }; Chris@102: Chris@102: Chris@102: }} // namespace detail::get_rescale_policy Chris@102: #endif // DOXYGEN_NO_DETAIL Chris@102: Chris@102: template Chris@102: struct rescale_policy_type Chris@102: : public detail::get_rescale_policy::rescale_policy_type Chris@102: < Chris@102: Point, Chris@102: #if defined(BOOST_GEOMETRY_NO_ROBUSTNESS) Chris@102: false Chris@102: #else Chris@102: boost::is_floating_point Chris@102: < Chris@102: typename geometry::coordinate_type::type Chris@102: >::type::value Chris@102: #endif Chris@102: > Chris@102: { Chris@102: static const bool is_point Chris@102: = boost::is_same Chris@102: < Chris@102: typename geometry::tag::type, Chris@102: geometry::point_tag Chris@102: >::type::value; Chris@102: Chris@102: BOOST_MPL_ASSERT_MSG((is_point), Chris@102: INVALID_INPUT_GEOMETRY, Chris@102: (typename geometry::tag::type)); Chris@102: }; Chris@102: Chris@102: Chris@102: template Chris@102: < Chris@102: typename Geometry1, Chris@102: typename Geometry2, Chris@102: typename Tag1 = typename tag_cast Chris@102: < Chris@102: typename tag::type, Chris@102: box_tag, Chris@102: pointlike_tag, Chris@102: linear_tag, Chris@102: areal_tag Chris@102: >::type, Chris@102: typename Tag2 = typename tag_cast Chris@102: < Chris@102: typename tag::type, Chris@102: box_tag, Chris@102: pointlike_tag, Chris@102: linear_tag, Chris@102: areal_tag Chris@102: >::type Chris@102: > Chris@102: struct rescale_overlay_policy_type Chris@102: // Default: no rescaling Chris@102: : public detail::get_rescale_policy::rescale_policy_type Chris@102: < Chris@102: typename geometry::point_type::type, Chris@102: false Chris@102: > Chris@102: {}; Chris@102: Chris@102: // Areal/areal: get rescale policy based on coordinate type Chris@102: template Chris@102: < Chris@102: typename Geometry1, Chris@102: typename Geometry2 Chris@102: > Chris@102: struct rescale_overlay_policy_type Chris@102: : public rescale_policy_type Chris@102: < Chris@102: typename geometry::point_type::type Chris@102: > Chris@102: {}; Chris@102: Chris@102: Chris@102: template Chris@102: inline Policy get_rescale_policy(Geometry const& geometry) Chris@102: { Chris@102: return detail::get_rescale_policy::get_rescale_policy::apply(geometry); Chris@102: } Chris@102: Chris@102: template Chris@102: inline Policy get_rescale_policy(Geometry1 const& geometry1, Geometry2 const& geometry2) Chris@102: { Chris@102: return detail::get_rescale_policy::get_rescale_policy::apply(geometry1, geometry2); Chris@102: } Chris@102: Chris@102: Chris@102: }} // namespace boost::geometry Chris@102: Chris@102: Chris@102: #endif // BOOST_GEOMETRY_POLICIES_ROBUSTNESS_GET_RESCALE_POLICY_HPP