summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/convex_hull.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/convex_hull.hpp')
-rw-r--r--boost/geometry/algorithms/convex_hull.hpp262
1 files changed, 179 insertions, 83 deletions
diff --git a/boost/geometry/algorithms/convex_hull.hpp b/boost/geometry/algorithms/convex_hull.hpp
index 56b87c8c15..09f4c5142d 100644
--- a/boost/geometry/algorithms/convex_hull.hpp
+++ b/boost/geometry/algorithms/convex_hull.hpp
@@ -4,6 +4,11 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -15,15 +20,20 @@
#define BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP
#include <boost/array.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/convex_hull.hpp>
#include <boost/geometry/strategies/concepts/convex_hull_concept.hpp>
+#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/views/detail/range_type.hpp>
@@ -40,45 +50,34 @@ namespace boost { namespace geometry
namespace detail { namespace convex_hull
{
-template
-<
- typename Geometry,
- order_selector Order,
- typename Strategy
->
+template <order_selector Order, closure_selector Closure>
struct hull_insert
{
// Member template function (to avoid inconvenient declaration
// of output-iterator-type, from hull_to_geometry)
- template <typename OutputIterator>
+ template <typename Geometry, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Geometry const& geometry,
OutputIterator out, Strategy const& strategy)
{
typename Strategy::state_type state;
strategy.apply(geometry, state);
- strategy.result(state, out, Order == clockwise);
+ strategy.result(state, out, Order == clockwise, Closure != open);
return out;
}
};
-template
-<
- typename Geometry,
- typename Strategy
->
struct hull_to_geometry
{
- template <typename OutputGeometry>
+ template <typename Geometry, typename OutputGeometry, typename Strategy>
static inline void apply(Geometry const& geometry, OutputGeometry& out,
Strategy const& strategy)
{
hull_insert
<
- Geometry,
geometry::point_order<OutputGeometry>::value,
- Strategy
+ geometry::closure<OutputGeometry>::value
>::apply(geometry,
std::back_inserter(
// Handle linestring, ring and polygon the same:
@@ -89,18 +88,6 @@ struct hull_to_geometry
}
};
-
-// Helper metafunction for default strategy retrieval
-template <typename Geometry>
-struct default_strategy
- : strategy_convex_hull
- <
- Geometry,
- typename point_type<Geometry>::type
- >
-{};
-
-
}} // namespace detail::convex_hull
#endif // DOXYGEN_NO_DETAIL
@@ -113,21 +100,16 @@ namespace dispatch
template
<
typename Geometry,
- typename Strategy = typename detail::convex_hull::default_strategy<Geometry>::type,
typename Tag = typename tag<Geometry>::type
>
struct convex_hull
- : detail::convex_hull::hull_to_geometry<Geometry, Strategy>
+ : detail::convex_hull::hull_to_geometry
{};
-template
-<
- typename Box,
- typename Strategy
->
-struct convex_hull<Box, Strategy, box_tag>
+template <typename Box>
+struct convex_hull<Box, box_tag>
{
- template <typename OutputGeometry>
+ template <typename OutputGeometry, typename Strategy>
static inline void apply(Box const& box, OutputGeometry& out,
Strategy const& )
{
@@ -149,13 +131,9 @@ struct convex_hull<Box, Strategy, box_tag>
-template
-<
- order_selector Order,
- typename Geometry, typename Strategy
->
+template <order_selector Order, closure_selector Closure>
struct convex_hull_insert
- : detail::convex_hull::hull_insert<Geometry, Order, Strategy>
+ : detail::convex_hull::hull_insert<Order, Closure>
{};
@@ -163,29 +141,170 @@ struct convex_hull_insert
#endif // DOXYGEN_NO_DISPATCH
-template<typename Geometry, typename OutputGeometry, typename Strategy>
-inline void convex_hull(Geometry const& geometry,
- OutputGeometry& out, Strategy const& strategy)
+namespace resolve_strategy {
+
+struct convex_hull
{
- concept::check_concepts_and_equal_dimensions
- <
+ template <typename Geometry, typename OutputGeometry, typename Strategy>
+ static inline void apply(Geometry const& geometry,
+ OutputGeometry& out,
+ Strategy const& strategy)
+ {
+ BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
+ dispatch::convex_hull<Geometry>::apply(geometry, out, strategy);
+ }
+
+ template <typename Geometry, typename OutputGeometry>
+ static inline void apply(Geometry const& geometry,
+ OutputGeometry& out,
+ default_strategy)
+ {
+ typedef typename strategy_convex_hull<
+ Geometry,
+ typename point_type<Geometry>::type
+ >::type strategy_type;
+
+ apply(geometry, out, strategy_type());
+ }
+};
+
+struct convex_hull_insert
+{
+ template <typename Geometry, typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(Geometry const& geometry,
+ OutputIterator& out,
+ Strategy const& strategy)
+ {
+ BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
+
+ return dispatch::convex_hull_insert<
+ geometry::point_order<Geometry>::value,
+ geometry::closure<Geometry>::value
+ >::apply(geometry, out, strategy);
+ }
+
+ template <typename Geometry, typename OutputIterator>
+ static inline OutputIterator apply(Geometry const& geometry,
+ OutputIterator& out,
+ default_strategy)
+ {
+ typedef typename strategy_convex_hull<
+ Geometry,
+ typename point_type<Geometry>::type
+ >::type strategy_type;
+
+ return apply(geometry, out, strategy_type());
+ }
+};
+
+} // namespace resolve_strategy
+
+
+namespace resolve_variant {
+
+template <typename Geometry>
+struct convex_hull
+{
+ template <typename OutputGeometry, typename Strategy>
+ static inline void apply(Geometry const& geometry, OutputGeometry& out, Strategy const& strategy)
+ {
+ concept::check_concepts_and_equal_dimensions<
const Geometry,
OutputGeometry
>();
- BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
+ resolve_strategy::convex_hull::apply(geometry, out, strategy);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct convex_hull<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename OutputGeometry, typename Strategy>
+ struct visitor: boost::static_visitor<void>
+ {
+ OutputGeometry& m_out;
+ Strategy const& m_strategy;
+
+ visitor(OutputGeometry& out, Strategy const& strategy)
+ : m_out(out), m_strategy(strategy)
+ {}
+
+ template <typename Geometry>
+ void operator()(Geometry const& geometry) const
+ {
+ convex_hull<Geometry>::apply(geometry, m_out, m_strategy);
+ }
+ };
+
+ template <typename OutputGeometry, typename Strategy>
+ static inline void
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ OutputGeometry& out,
+ Strategy const& strategy)
+ {
+ boost::apply_visitor(visitor<OutputGeometry, Strategy>(out, strategy), geometry);
+ }
+};
+
+template <typename Geometry>
+struct convex_hull_insert
+{
+ template <typename OutputIterator, typename Strategy>
+ static inline OutputIterator apply(Geometry const& geometry, OutputIterator& out, Strategy const& strategy)
+ {
+ // Concept: output point type = point type of input geometry
+ concept::check<Geometry const>();
+ concept::check<typename point_type<Geometry>::type>();
+
+ return resolve_strategy::convex_hull_insert::apply(geometry, out, strategy);
+ }
+};
+
+template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct convex_hull_insert<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ template <typename OutputIterator, typename Strategy>
+ struct visitor: boost::static_visitor<OutputIterator>
+ {
+ OutputIterator& m_out;
+ Strategy const& m_strategy;
+
+ visitor(OutputIterator& out, Strategy const& strategy)
+ : m_out(out), m_strategy(strategy)
+ {}
+ template <typename Geometry>
+ OutputIterator operator()(Geometry const& geometry) const
+ {
+ return convex_hull_insert<Geometry>::apply(geometry, m_out, m_strategy);
+ }
+ };
+
+ template <typename OutputIterator, typename Strategy>
+ static inline OutputIterator
+ apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
+ OutputIterator& out,
+ Strategy const& strategy)
+ {
+ return boost::apply_visitor(visitor<OutputIterator, Strategy>(out, strategy), geometry);
+ }
+};
+
+} // namespace resolve_variant
+
+
+template<typename Geometry, typename OutputGeometry, typename Strategy>
+inline void convex_hull(Geometry const& geometry,
+ OutputGeometry& out, Strategy const& strategy)
+{
if (geometry::num_points(geometry) == 0)
{
// Leave output empty
return;
}
- dispatch::convex_hull
- <
- Geometry,
- Strategy
- >::apply(geometry, out, strategy);
+ resolve_variant::convex_hull<Geometry>::apply(geometry, out, strategy);
}
@@ -193,8 +312,8 @@ inline void convex_hull(Geometry const& geometry,
\brief \brief_calc{convex hull}
\ingroup convex_hull
\details \details_calc{convex_hull,convex hull}.
-\tparam Geometry1 \tparam_geometry
-\tparam Geometry2 \tparam_geometry
+\tparam Geometry the input geometry type
+\tparam OutputGeometry the output geometry type
\param geometry \param_geometry, input geometry
\param hull \param_geometry \param_set{convex hull}
@@ -204,15 +323,7 @@ template<typename Geometry, typename OutputGeometry>
inline void convex_hull(Geometry const& geometry,
OutputGeometry& hull)
{
- concept::check_concepts_and_equal_dimensions
- <
- const Geometry,
- OutputGeometry
- >();
-
- typedef typename detail::convex_hull::default_strategy<Geometry>::type strategy_type;
-
- convex_hull(geometry, hull, strategy_type());
+ convex_hull(geometry, hull, default_strategy());
}
#ifndef DOXYGEN_NO_DETAIL
@@ -224,17 +335,8 @@ template<typename Geometry, typename OutputIterator, typename Strategy>
inline OutputIterator convex_hull_insert(Geometry const& geometry,
OutputIterator out, Strategy const& strategy)
{
- // Concept: output point type = point type of input geometry
- concept::check<Geometry const>();
- concept::check<typename point_type<Geometry>::type>();
-
- BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
-
- return dispatch::convex_hull_insert
- <
- geometry::point_order<Geometry>::value,
- Geometry, Strategy
- >::apply(geometry, out, strategy);
+ return resolve_variant::convex_hull_insert<Geometry>
+ ::apply(geometry, out, strategy);
}
@@ -255,13 +357,7 @@ template<typename Geometry, typename OutputIterator>
inline OutputIterator convex_hull_insert(Geometry const& geometry,
OutputIterator out)
{
- // Concept: output point type = point type of input geometry
- concept::check<Geometry const>();
- concept::check<typename point_type<Geometry>::type>();
-
- typedef typename detail::convex_hull::default_strategy<Geometry>::type strategy_type;
-
- return convex_hull_insert(geometry, out, strategy_type());
+ return convex_hull_insert(geometry, out, default_strategy());
}