From e30bf569ad183f3bbc9fb4cf5015ca9595ffee33 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 7 Jun 2022 23:22:35 +0200 Subject: [PATCH] [crosses] Add support for GC. --- include/boost/geometry/algorithms/crosses.hpp | 281 ++++++++++-------- .../boost/geometry/algorithms/detail/gc.hpp | 51 ++++ .../algorithms/detail/relate/de9im.hpp | 19 +- 3 files changed, 229 insertions(+), 122 deletions(-) create mode 100644 include/boost/geometry/algorithms/detail/gc.hpp diff --git a/include/boost/geometry/algorithms/crosses.hpp b/include/boost/geometry/algorithms/crosses.hpp index 96b8e8681..372b6626b 100644 --- a/include/boost/geometry/algorithms/crosses.hpp +++ b/include/boost/geometry/algorithms/crosses.hpp @@ -22,19 +22,18 @@ #include -#include -#include -#include - -#include +#include #include +#include #include +#include #include #include #include #include #include #include +#include namespace boost { namespace geometry @@ -62,6 +61,82 @@ struct crosses {}; +template +struct crosses +{ + template + static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, + Strategy const& strategy) + { + int dimension1 = detail::gc_topological_dimension(geometry1); + int dimension2 = detail::gc_topological_dimension(geometry2); + + if (dimension1 >= 0 && dimension2 >= 0) + { + if (dimension1 < dimension2) + { + return detail::relate::relate_impl + < + detail::de9im::static_mask_crosses_d1_le_d2_type, + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, strategy); + } + else if (dimension1 > dimension2) + { + return detail::relate::relate_impl + < + detail::de9im::static_mask_crosses_d2_le_d1_type, + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, strategy); + } + else if (dimension1 == 1 && dimension2 == 1) + { + return detail::relate::relate_impl + < + detail::de9im::static_mask_crosses_d1_1_d2_1_type, + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, strategy); + } + } + + return false; + } +}; + +template +struct crosses +{ + template + static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, + Strategy const& strategy) + { + using gc1_view_t = detail::geometry_collection_view; + return crosses + < + gc1_view_t, Geometry2 + >::apply(gc1_view_t(geometry1), geometry2, strategy); + } +}; + +template +struct crosses +{ + template + static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, + Strategy const& strategy) + { + using gc2_view_t = detail::geometry_collection_view; + return crosses + < + Geometry1, gc2_view_t + >::apply(geometry1, gc2_view_t(geometry2), strategy); + } +}; + + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH @@ -134,128 +209,94 @@ struct crosses } // namespace resolve_strategy -namespace resolve_variant +namespace resolve_dynamic { - template - struct crosses + +template +< + typename Geometry1, typename Geometry2, + typename Tag1 = typename geometry::tag::type, + typename Tag2 = typename geometry::tag::type +> +struct crosses +{ + template + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) { - template - static inline bool apply(Geometry1 const& geometry1, - Geometry2 const& geometry2, - Strategy const& strategy) + return resolve_strategy::crosses + < + Strategy + >::apply(geometry1, geometry2, strategy); + } +}; + + +template +struct crosses +{ + template + static inline bool apply(DynamicGeometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + bool result = false; + traits::visit::apply([&](auto const& g1) { - return resolve_strategy::crosses + result = resolve_strategy::crosses < Strategy - >::apply(geometry1, geometry2, strategy); - } - }; - - - template - struct crosses, Geometry2> - { - template - struct visitor: static_visitor - { - Geometry2 const& m_geometry2; - Strategy const& m_strategy; - - visitor(Geometry2 const& geometry2, Strategy const& strategy) - : m_geometry2(geometry2) - , m_strategy(strategy) - {} - - template - result_type operator()(Geometry1 const& geometry1) const - { - return crosses - < - Geometry1, - Geometry2 - >::apply(geometry1, m_geometry2, m_strategy); - } - }; - - template - static inline bool apply(variant const& geometry1, - Geometry2 const& geometry2, - Strategy const& strategy) - { - return boost::apply_visitor(visitor(geometry2, strategy), geometry1); - } - }; - - - template - struct crosses > - { - template - struct visitor: static_visitor - { - Geometry1 const& m_geometry1; - Strategy const& m_strategy; - - visitor(Geometry1 const& geometry1, Strategy const& strategy) - : m_geometry1(geometry1) - , m_strategy(strategy) - {} - - template - result_type operator()(Geometry2 const& geometry2) const - { - return crosses - < - Geometry1, - Geometry2 - >::apply(m_geometry1, geometry2, m_strategy); - } - }; - - template - static inline bool apply(Geometry1 const& geometry1, - variant const& geometry2, - Strategy const& strategy) - { - return boost::apply_visitor(visitor(geometry1, strategy), geometry2); - } - }; - - - template - struct crosses, variant > - { - template - struct visitor: static_visitor - { - Strategy const& m_strategy; + >::apply(g1, geometry2, strategy); + }, geometry1); + return result; + } +}; - visitor(Strategy const& strategy) - : m_strategy(strategy) - {} - template - result_type operator()(Geometry1 const& geometry1, - Geometry2 const& geometry2) const - { - return crosses - < - Geometry1, - Geometry2 - >::apply(geometry1, geometry2, m_strategy); - } - }; - - template - static inline bool apply(variant const& geometry1, - variant const& geometry2, - Strategy const& strategy) +template +struct crosses +{ + template + static inline bool apply(Geometry1 const& geometry1, + DynamicGeometry2 const& geometry2, + Strategy const& strategy) + { + bool result = false; + traits::visit::apply([&](auto const& g2) { - return boost::apply_visitor(visitor(strategy), geometry1, geometry2); - } - }; + result = resolve_strategy::crosses + < + Strategy + >::apply(geometry1, g2, strategy); + }, geometry2); + return result; + } +}; + + +template +struct crosses +{ + template + static inline bool apply(DynamicGeometry1 const& geometry1, + DynamicGeometry2 const& geometry2, + Strategy const& strategy) + { + bool result = false; + traits::visit::apply([&](auto const& g1, auto const& g2) + { + result = resolve_strategy::crosses + < + Strategy + >::apply(g1, g2, strategy); + }, geometry1, geometry2); + return result; + } +}; + -} // namespace resolve_variant +} // namespace resolve_dynamic /*! @@ -277,7 +318,7 @@ inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) { - return resolve_variant::crosses + return resolve_dynamic::crosses < Geometry1, Geometry2 >::apply(geometry1, geometry2, strategy); @@ -302,7 +343,7 @@ inline bool crosses(Geometry1 const& geometry1, template inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2) { - return resolve_variant::crosses + return resolve_dynamic::crosses < Geometry1, Geometry2 >::apply(geometry1, geometry2, default_strategy()); diff --git a/include/boost/geometry/algorithms/detail/gc.hpp b/include/boost/geometry/algorithms/detail/gc.hpp new file mode 100644 index 000000000..e91e7cc14 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/gc.hpp @@ -0,0 +1,51 @@ +// Boost.Geometry + +// Copyright (c) 2022, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GC_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GC_HPP + + +#include + +#include +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + + +template +inline int gc_topological_dimension(GeometryCollection const& geometry) +{ + int result = -1; + detail::visit_breadth_first([&](auto const& g) + { + if (! geometry::is_empty(g)) + { + static const int d = geometry::topological_dimension::value; + result = (std::max)(result, d); + } + return result >= 2; + }, geometry); + return result; +} + + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_GC_HPP diff --git a/include/boost/geometry/algorithms/detail/relate/de9im.hpp b/include/boost/geometry/algorithms/detail/relate/de9im.hpp index a89d46100..29c2568e8 100644 --- a/include/boost/geometry/algorithms/detail/relate/de9im.hpp +++ b/include/boost/geometry/algorithms/detail/relate/de9im.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013-2020. -// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2022. +// Modifications copyright (c) 2013-2022 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -344,6 +344,21 @@ struct static_mask_crosses_type : static_mask_crosses_impl {}; +template +struct static_mask_crosses_d1_le_d2_type // specific dimensions are not important here + : static_mask_crosses_impl +{}; + +template +struct static_mask_crosses_d2_le_d1_type // specific dimensions are not important here + : static_mask_crosses_impl +{}; + +template +struct static_mask_crosses_d1_1_d2_1_type + : static_mask_crosses_impl +{}; + // OVERLAPS // dim(G1) != dim(G2) - NOT P/P, L/L, A/A