// Boost.Geometry
-// Copyright (c) 2017-2018, Oracle and/or its affiliates.
+// Copyright (c) 2017-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#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/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.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/range.hpp>
-#include <boost/range/size.hpp>
-#include <boost/range/value_type.hpp>
-
-#include <boost/throw_exception.hpp>
-
namespace boost { namespace geometry
{
template <bool AppendLastPoint = true>
struct densify_range
{
- template <typename FwdRng, typename MutRng, typename T, typename Strategy>
+ template <typename FwdRng, typename MutRng, typename T, typename Strategies>
static inline void apply(FwdRng const& rng, MutRng & rng_out,
- T const& len, Strategy const& strategy)
+ 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;
return;
}
+ auto strategy = strategies.densify(rng);
push_back_policy<MutRng> policy(rng_out);
iterator_t prev = it;
template <bool IsClosed1, bool IsClosed2> // false, X
struct densify_ring
{
- template <typename Geometry, typename GeometryOut, typename T, typename Strategy>
+ template <typename Geometry, typename GeometryOut, typename T, typename Strategies>
static inline void apply(Geometry const& ring, GeometryOut & ring_out,
- T const& len, Strategy const& strategy)
+ T const& len, Strategies const& strategies)
{
geometry::detail::densify::densify_range<true>
- ::apply(ring, ring_out, len, strategy);
+ ::apply(ring, ring_out, len, strategies);
if (boost::size(ring) <= 1)
return;
point_t const& p0 = range::back(ring);
point_t const& p1 = range::front(ring);
+ auto strategy = strategies.densify(ring);
push_back_policy<GeometryOut> policy(ring_out);
strategy.apply(p0, p1, policy, len);
: 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
: not_implemented<Tag1, Tag2>
{};
+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<>
namespace resolve_strategy
{
+template
+<
+ typename Strategies,
+ bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategies>::value
+>
struct densify
{
- template <typename Geometry, typename Distance, typename Strategy>
+ template <typename Geometry, typename Distance>
+ static inline void apply(Geometry const& geometry,
+ Geometry& out,
+ Distance const& max_distance,
+ Strategies const& strategies)
+ {
+ dispatch::densify
+ <
+ Geometry, Geometry
+ >::apply(geometry, out, max_distance, strategies);
+ }
+};
+
+template <typename Strategy>
+struct densify<Strategy, false>
+{
+ template <typename Geometry, typename Distance>
static inline void apply(Geometry const& geometry,
Geometry& out,
Distance const& max_distance,
Strategy const& strategy)
{
- dispatch::densify<Geometry, Geometry>
- ::apply(geometry, out, max_distance, strategy);
+ using strategies::densify::services::strategy_converter;
+
+ dispatch::densify
+ <
+ Geometry, Geometry
+ >::apply(geometry, out, max_distance,
+ strategy_converter<Strategy>::get(strategy));
}
+};
+template <>
+struct densify<default_strategy, false>
+{
template <typename Geometry, typename Distance>
static inline void apply(Geometry const& geometry,
Geometry& out,
Distance const& max_distance,
- default_strategy)
+ default_strategy const&)
{
- typedef typename strategy::densify::services::default_strategy
+ typedef typename strategies::densify::services::default_strategy
<
- typename cs_tag<Geometry>::type
- >::type strategy_type;
+ Geometry
+ >::type strategies_type;
- /*BOOST_CONCEPT_ASSERT(
- (concepts::DensifyStrategy<strategy_type>)
- );*/
-
- apply(geometry, out, max_distance, strategy_type());
+ dispatch::densify
+ <
+ Geometry, Geometry
+ >::apply(geometry, out, max_distance, strategies_type());
}
};
} // 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>
Distance const& max_distance,
Strategy const& strategy)
{
- resolve_strategy::densify::apply(geometry, out, max_distance, strategy);
+ resolve_strategy::densify
+ <
+ Strategy
+ >::apply(geometry, out, max_distance, strategy);
}
};
-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
/*!
geometry::clear(out);
- resolve_variant::densify
+ resolve_dynamic::densify
<
Geometry
>::apply(geometry, out, max_distance, strategy);