diff options
Diffstat (limited to 'boost/geometry/algorithms/densify.hpp')
-rw-r--r-- | boost/geometry/algorithms/densify.hpp | 129 |
1 files changed, 82 insertions, 47 deletions
diff --git a/boost/geometry/algorithms/densify.hpp b/boost/geometry/algorithms/densify.hpp index d601bd3c83..3af062ebd3 100644 --- a/boost/geometry/algorithms/densify.hpp +++ b/boost/geometry/algorithms/densify.hpp @@ -1,7 +1,9 @@ // Boost.Geometry -// Copyright (c) 2017-2021, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. @@ -11,28 +13,29 @@ #define BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP +#include <boost/range/size.hpp> +#include <boost/range/value_type.hpp> +#include <boost/throw_exception.hpp> + #include <boost/geometry/algorithms/clear.hpp> +#include <boost/geometry/algorithms/convert.hpp> #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp> +#include <boost/geometry/algorithms/detail/visit.hpp> #include <boost/geometry/algorithms/not_implemented.hpp> #include <boost/geometry/core/closure.hpp> -#include <boost/geometry/core/cs.hpp> #include <boost/geometry/core/exception.hpp> -#include <boost/geometry/core/point_type.hpp> #include <boost/geometry/core/tag.hpp> #include <boost/geometry/core/tags.hpp> +#include <boost/geometry/core/visit.hpp> +#include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility #include <boost/geometry/strategies/default_strategy.hpp> #include <boost/geometry/strategies/densify/cartesian.hpp> #include <boost/geometry/strategies/densify/geographic.hpp> #include <boost/geometry/strategies/densify/spherical.hpp> #include <boost/geometry/strategies/detail.hpp> -#include <boost/geometry/util/condition.hpp> +#include <boost/geometry/util/constexpr.hpp> #include <boost/geometry/util/range.hpp> -#include <boost/range/size.hpp> -#include <boost/range/value_type.hpp> - -#include <boost/throw_exception.hpp> - namespace boost { namespace geometry { @@ -75,21 +78,20 @@ struct densify_range static inline void apply(FwdRng const& rng, MutRng & rng_out, T const& len, Strategies const& strategies) { - typedef typename boost::range_iterator<FwdRng const>::type iterator_t; typedef typename boost::range_value<FwdRng>::type point_t; - iterator_t it = boost::begin(rng); - iterator_t end = boost::end(rng); + auto it = boost::begin(rng); + auto const end = boost::end(rng); if (it == end) // empty(rng) { return; } - + auto strategy = strategies.densify(rng); push_back_policy<MutRng> policy(rng_out); - iterator_t prev = it; + auto prev = it; for ( ++it ; it != end ; prev = it++) { point_t const& p0 = *prev; @@ -100,7 +102,7 @@ struct densify_range strategy.apply(p0, p1, policy, len); } - if (BOOST_GEOMETRY_CONDITION(AppendLastPoint)) + if BOOST_GEOMETRY_CONSTEXPR (AppendLastPoint) { convert_and_push_back(rng_out, *prev); // back(rng) } @@ -120,16 +122,15 @@ struct densify_ring if (boost::size(ring) <= 1) return; - typedef typename point_type<Geometry>::type point_t; - point_t const& p0 = range::back(ring); - point_t const& p1 = range::front(ring); + auto const& p0 = range::back(ring); + auto const& p1 = range::front(ring); auto strategy = strategies.densify(ring); push_back_policy<GeometryOut> policy(ring_out); strategy.apply(p0, p1, policy, len); - if (BOOST_GEOMETRY_CONDITION(IsClosed2)) + if BOOST_GEOMETRY_CONSTEXPR (IsClosed2) { convert_and_push_back(ring_out, p1); } @@ -146,6 +147,15 @@ struct densify_ring<true, false> : densify_range<false> {}; +struct densify_convert +{ + template <typename GeometryIn, typename GeometryOut, typename T, typename Strategy> + static void apply(GeometryIn const& in, GeometryOut &out, + T const& , Strategy const& ) + { + geometry::convert(in, out); + } +}; }} // namespace detail::densify #endif // DOXYGEN_NO_DETAIL @@ -168,6 +178,26 @@ struct densify {}; template <typename Geometry, typename GeometryOut> +struct densify<Geometry, GeometryOut, point_tag, point_tag> + : geometry::detail::densify::densify_convert +{}; + +template <typename Geometry, typename GeometryOut> +struct densify<Geometry, GeometryOut, segment_tag, segment_tag> + : geometry::detail::densify::densify_convert +{}; + +template <typename Geometry, typename GeometryOut> +struct densify<Geometry, GeometryOut, box_tag, box_tag> + : geometry::detail::densify::densify_convert +{}; + +template <typename Geometry, typename GeometryOut> +struct densify<Geometry, GeometryOut, multi_point_tag, multi_point_tag> + : geometry::detail::densify::densify_convert +{}; + +template <typename Geometry, typename GeometryOut> struct densify<Geometry, GeometryOut, linestring_tag, linestring_tag> : geometry::detail::densify::densify_range<> {}; @@ -317,7 +347,7 @@ struct densify<default_strategy, false> < Geometry >::type strategies_type; - + dispatch::densify < Geometry, Geometry @@ -328,9 +358,9 @@ struct densify<default_strategy, false> } // namespace resolve_strategy -namespace resolve_variant { +namespace resolve_dynamic { -template <typename Geometry> +template <typename Geometry, typename Tag = typename tag<Geometry>::type> struct densify { template <typename Distance, typename Strategy> @@ -346,43 +376,48 @@ struct densify } }; -template <BOOST_VARIANT_ENUM_PARAMS(typename T)> -struct densify<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > +template <typename Geometry> +struct densify<Geometry, dynamic_geometry_tag> { template <typename Distance, typename Strategy> - struct visitor: boost::static_visitor<void> + static inline void + apply(Geometry const& geometry, + Geometry& out, + Distance const& max_distance, + Strategy const& strategy) { - Distance const& m_max_distance; - Strategy const& m_strategy; - - visitor(Distance const& max_distance, Strategy const& strategy) - : m_max_distance(max_distance) - , m_strategy(strategy) - {} - - template <typename Geometry> - void operator()(Geometry const& geometry, Geometry& out) const + traits::visit<Geometry>::apply([&](auto const& g) { - densify<Geometry>::apply(geometry, out, m_max_distance, m_strategy); - } - }; + using geom_t = util::remove_cref_t<decltype(g)>; + geom_t o; + densify<geom_t>::apply(g, o, max_distance, strategy); + out = std::move(o); + }, geometry); + } +}; +template <typename Geometry> +struct densify<Geometry, geometry_collection_tag> +{ template <typename Distance, typename Strategy> static inline void - apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry, - boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& out, + apply(Geometry const& geometry, + Geometry& out, Distance const& max_distance, Strategy const& strategy) { - boost::apply_visitor( - visitor<Distance, Strategy>(max_distance, strategy), - geometry, - out - ); + detail::visit_breadth_first([&](auto const& g) + { + using geom_t = util::remove_cref_t<decltype(g)>; + geom_t o; + densify<geom_t>::apply(g, o, max_distance, strategy); + traits::emplace_back<Geometry>::apply(out, std::move(o)); + return true; + }, geometry); } }; -} // namespace resolve_variant +} // namespace resolve_dynamic /*! @@ -428,7 +463,7 @@ inline void densify(Geometry const& geometry, geometry::clear(out); - resolve_variant::densify + resolve_dynamic::densify < Geometry >::apply(geometry, out, max_distance, strategy); |