diff options
Diffstat (limited to 'boost/geometry/algorithms/touches.hpp')
-rw-r--r-- | boost/geometry/algorithms/touches.hpp | 212 |
1 files changed, 166 insertions, 46 deletions
diff --git a/boost/geometry/algorithms/touches.hpp b/boost/geometry/algorithms/touches.hpp index 6384cc2a88..49e104d258 100644 --- a/boost/geometry/algorithms/touches.hpp +++ b/boost/geometry/algorithms/touches.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2015. -// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017. +// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -104,8 +104,8 @@ struct box_box_loop<DimensionCount, DimensionCount> struct box_box { - template <typename Box1, typename Box2> - static inline bool apply(Box1 const& b1, Box2 const& b2) + template <typename Box1, typename Box2, typename Strategy> + static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& /*strategy*/) { BOOST_STATIC_ASSERT((boost::is_same < @@ -205,15 +205,17 @@ struct areal_interrupt_policy } }; -template<typename Geometry> +template<typename Geometry, typename PointInRingStrategy> struct check_each_ring_for_within { bool has_within; Geometry const& m_geometry; + PointInRingStrategy const& m_strategy; - inline check_each_ring_for_within(Geometry const& g) + inline check_each_ring_for_within(Geometry const& g, PointInRingStrategy const& strategy) : has_within(false) , m_geometry(g) + , m_strategy(strategy) {} template <typename Range> @@ -221,18 +223,31 @@ struct check_each_ring_for_within { typename geometry::point_type<Range>::type p; geometry::point_on_border(p, range); - if ( !has_within && geometry::within(p, m_geometry) ) + if ( !has_within && geometry::within(p, m_geometry, m_strategy) ) { has_within = true; } } }; -template <typename FirstGeometry, typename SecondGeometry> +template <typename FirstGeometry, typename SecondGeometry, typename IntersectionStrategy> inline bool rings_containing(FirstGeometry const& geometry1, - SecondGeometry const& geometry2) + SecondGeometry const& geometry2, + IntersectionStrategy const& strategy) { - check_each_ring_for_within<FirstGeometry> checker(geometry1); + // NOTE: This strategy could be defined inside IntersectionStrategy + typedef typename IntersectionStrategy::template point_in_geometry_strategy + < + FirstGeometry, SecondGeometry + >::type point_in_ring_strategy_type; + + point_in_ring_strategy_type point_in_ring_strategy + = strategy.template get_point_in_geometry_strategy<FirstGeometry, SecondGeometry>(); + + check_each_ring_for_within + < + FirstGeometry, point_in_ring_strategy_type + > checker(geometry1, point_in_ring_strategy); geometry::detail::for_each_range(geometry2, checker); return checker.has_within; } @@ -240,8 +255,10 @@ inline bool rings_containing(FirstGeometry const& geometry1, template <typename Geometry1, typename Geometry2> struct areal_areal { - static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + template <typename IntersectionStrategy> + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + IntersectionStrategy const& strategy) { typedef detail::no_rescale_policy rescale_policy_type; typedef typename geometry::point_type<Geometry1>::type point_type; @@ -259,11 +276,11 @@ struct areal_areal detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value, detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value, detail::overlay::assign_null_policy - >(geometry1, geometry2, robust_policy, turns, policy); + >(geometry1, geometry2, strategy, robust_policy, turns, policy); return policy.result() - && ! geometry::detail::touches::rings_containing(geometry1, geometry2) - && ! geometry::detail::touches::rings_containing(geometry2, geometry1); + && ! geometry::detail::touches::rings_containing(geometry1, geometry2, strategy) + && ! geometry::detail::touches::rings_containing(geometry2, geometry1, strategy); } }; @@ -271,10 +288,10 @@ struct areal_areal struct use_point_in_geometry { - template <typename Point, typename Geometry> - static inline bool apply(Point const& point, Geometry const& geometry) + template <typename Point, typename Geometry, typename Strategy> + static inline bool apply(Point const& point, Geometry const& geometry, Strategy const& strategy) { - return detail::within::point_in_geometry(point, geometry) == 0; + return detail::within::point_in_geometry(point, geometry, strategy) == 0; } }; @@ -288,7 +305,8 @@ namespace dispatch { template < - typename Geometry1, typename Geometry2, + typename Geometry1, + typename Geometry2, typename Tag1 = typename tag<Geometry1>::type, typename Tag2 = typename tag<Geometry2>::type, typename CastedTag1 = typename tag_cast<Tag1, pointlike_tag, linear_tag, areal_tag>::type, @@ -309,18 +327,30 @@ template struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true> : touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false> { - static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) + template <typename Strategy> + static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) { - return touches<Geometry2, Geometry1>::apply(g2, g1); + return touches<Geometry2, Geometry1>::apply(g2, g1, strategy); } }; // P/P -template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2> -struct touches<Geometry1, Geometry2, Tag1, Tag2, pointlike_tag, pointlike_tag, false> +template <typename Geometry1, typename Geometry2, typename Tag2> +struct touches<Geometry1, Geometry2, point_tag, Tag2, pointlike_tag, pointlike_tag, false> { - static inline bool apply(Geometry1 const& , Geometry2 const& ) + template <typename Strategy> + static inline bool apply(Geometry1 const& , Geometry2 const& , Strategy const&) + { + return false; + } +}; + +template <typename Geometry1, typename Geometry2, typename Tag2> +struct touches<Geometry1, Geometry2, multi_point_tag, Tag2, pointlike_tag, pointlike_tag, false> +{ + template <typename Strategy> + static inline bool apply(Geometry1 const&, Geometry2 const&, Strategy const&) { return false; } @@ -403,66 +433,115 @@ struct touches<Areal1, Areal2, ring_tag, ring_tag, areal_tag, areal_tag, false> #endif // DOXYGEN_NO_DISPATCH +namespace resolve_strategy +{ + +struct touches +{ + template <typename Geometry1, typename Geometry2, typename Strategy> + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + return dispatch::touches + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); + } + + template <typename Geometry1, typename Geometry2> + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + default_strategy) + { + typedef typename strategy::relate::services::default_strategy + < + Geometry1, + Geometry2 + >::type strategy_type; + + return dispatch::touches + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy_type()); + } +}; + +} // namespace resolve_strategy + + namespace resolve_variant { template <typename Geometry1, typename Geometry2> struct touches { - static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + template <typename Strategy> + static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) { concepts::check<Geometry1 const>(); concepts::check<Geometry2 const>(); - return dispatch::touches<Geometry1, Geometry2> - ::apply(geometry1, geometry2); + return resolve_strategy::touches::apply(geometry1, geometry2, strategy); } }; template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2> struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2> { + template <typename Strategy> struct visitor: boost::static_visitor<bool> { Geometry2 const& m_geometry2; + Strategy const& m_strategy; - visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {} + visitor(Geometry2 const& geometry2, Strategy const& strategy) + : m_geometry2(geometry2) + , m_strategy(strategy) + {} template <typename Geometry1> bool operator()(Geometry1 const& geometry1) const { - return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2); + return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2, m_strategy); } }; - static inline bool - apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1, - Geometry2 const& geometry2) + template <typename Strategy> + static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry2), geometry1); + return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1); } }; template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)> struct touches<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > { + template <typename Strategy> struct visitor: boost::static_visitor<bool> { Geometry1 const& m_geometry1; + Strategy const& m_strategy; - visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {} + visitor(Geometry1 const& geometry1, Strategy const& strategy) + : m_geometry1(geometry1) + , m_strategy(strategy) + {} template <typename Geometry2> bool operator()(Geometry2 const& geometry2) const { - return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2); + return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2, m_strategy); } }; - static inline bool - apply(Geometry1 const& geometry1, - boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2) + template <typename Strategy> + static inline bool apply(Geometry1 const& geometry1, + boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(geometry1), geometry2); + return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2); } }; @@ -471,21 +550,29 @@ template <BOOST_VARIANT_ENUM_PARAMS(typename T1), struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> > { + template <typename Strategy> struct visitor: boost::static_visitor<bool> { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) + : m_strategy(strategy) + {} + template <typename Geometry1, typename Geometry2> bool operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const { - return touches<Geometry1, Geometry2>::apply(geometry1, geometry2); + return touches<Geometry1, Geometry2>::apply(geometry1, geometry2, m_strategy); } }; - static inline bool - apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1, - boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2) + template <typename Strategy> + static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1, + boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2, + Strategy const& strategy) { - return boost::apply_visitor(visitor(), geometry1, geometry2); + return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2); } }; @@ -496,6 +583,10 @@ struct self_touches { concepts::check<Geometry const>(); + typedef typename strategy::relate::services::default_strategy + < + Geometry, Geometry + >::type strategy_type; typedef detail::no_rescale_policy rescale_policy_type; typedef typename geometry::point_type<Geometry>::type point_type; typedef detail::overlay::turn_info @@ -511,11 +602,12 @@ struct self_touches std::deque<turn_info> turns; detail::touches::areal_interrupt_policy policy; + strategy_type strategy; rescale_policy_type robust_policy; detail::self_get_turn_points::get_turns < policy_type - >::apply(geometry, robust_policy, turns, policy); + >::apply(geometry, strategy, robust_policy, turns, policy); return policy.result(); } @@ -578,7 +670,35 @@ inline bool touches(Geometry const& geometry) template <typename Geometry1, typename Geometry2> inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2) { - return resolve_variant::touches<Geometry1, Geometry2>::apply(geometry1, geometry2); + return resolve_variant::touches + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, default_strategy()); +} + +/*! +\brief \brief_check2{have at least one touching point (tangent - non overlapping)} +\ingroup touches +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Touches} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{touches} +\return \return_check2{touch each other} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/touches.qbk]} + */ +template <typename Geometry1, typename Geometry2, typename Strategy> +inline bool touches(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + return resolve_variant::touches + < + Geometry1, Geometry2 + >::apply(geometry1, geometry2, strategy); } |