]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/geometry/algorithms/detail/envelope/multipoint.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / envelope / multipoint.hpp
index eef7563796d5f873a025e9885a5dd552c82f9172..ce112e4d780d52991ea11e2321e3f80af4ecd85d 100644 (file)
@@ -1,6 +1,6 @@
 // Boost.Geometry (aka GGL, Generic Geometry Library)
 
-// Copyright (c) 2015-2017, Oracle and/or its affiliates.
+// Copyright (c) 2015-2018, Oracle and/or its affiliates.
 
 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
 
-#include <cstddef>
-#include <algorithm>
-#include <utility>
-#include <vector>
-
-#include <boost/algorithm/minmax_element.hpp>
-#include <boost/range.hpp>
-
-#include <boost/geometry/core/access.hpp>
-#include <boost/geometry/core/assert.hpp>
-#include <boost/geometry/core/coordinate_system.hpp>
-#include <boost/geometry/core/coordinate_type.hpp>
 #include <boost/geometry/core/tags.hpp>
 
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/range.hpp>
-
-#include <boost/geometry/geometries/helper_geometry.hpp>
-
-#include <boost/geometry/algorithms/detail/normalize.hpp>
-
-#include <boost/geometry/algorithms/detail/envelope/box.hpp>
-#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
-#include <boost/geometry/algorithms/detail/envelope/range.hpp>
-#include <boost/geometry/algorithms/detail/expand/point.hpp>
-
 #include <boost/geometry/algorithms/dispatch/envelope.hpp>
 
+// For backward compatibility
+#include <boost/geometry/strategies/cartesian/envelope_multipoint.hpp>
+#include <boost/geometry/strategies/spherical/envelope_multipoint.hpp>
 
 namespace boost { namespace geometry
 {
 
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace envelope
-{
-
-
-class envelope_multipoint_on_spheroid
-{
-private:
-    template <std::size_t Dim>
-    struct coordinate_less
-    {
-        template <typename Point>
-        inline bool operator()(Point const& point1, Point const& point2) const
-        {
-            return math::smaller(geometry::get<Dim>(point1),
-                                 geometry::get<Dim>(point2));
-        }
-    };
-
-    template <typename Constants, typename MultiPoint, typename OutputIterator>
-    static inline void analyze_point_coordinates(MultiPoint const& multipoint,
-                                                 bool& has_south_pole,
-                                                 bool& has_north_pole,
-                                                 OutputIterator oit)
-    {
-        typedef typename boost::range_value<MultiPoint>::type point_type;
-        typedef typename boost::range_iterator
-            <
-                MultiPoint const
-            >::type iterator_type;
-
-        // analyze point coordinates:
-        // (1) normalize point coordinates
-        // (2) check if any point is the north or the south pole
-        // (3) put all non-pole points in a container
-        //
-        // notice that at this point in the algorithm, we have at
-        // least two points on the spheroid
-        has_south_pole = false;
-        has_north_pole = false;
-
-        for (iterator_type it = boost::begin(multipoint);
-             it != boost::end(multipoint);
-             ++it)
-        {
-            point_type point = detail::return_normalized<point_type>(*it);
-
-            if (math::equals(geometry::get<1>(point),
-                             Constants::min_latitude()))
-            {
-                has_south_pole = true;
-            }
-            else if (math::equals(geometry::get<1>(point),
-                                  Constants::max_latitude()))
-            {
-                has_north_pole = true;
-            }
-            else
-            {
-                *oit++ = point;
-            }
-        }
-    }
-
-    template <typename SortedRange, typename Value>
-    static inline Value maximum_gap(SortedRange const& sorted_range,
-                                    Value& max_gap_left,
-                                    Value& max_gap_right)
-    {
-        typedef typename boost::range_iterator
-            <
-                SortedRange const
-            >::type iterator_type;
-
-        iterator_type it1 = boost::begin(sorted_range), it2 = it1;
-        ++it2;
-        max_gap_left = geometry::get<0>(*it1);
-        max_gap_right = geometry::get<0>(*it2);
-
-        Value max_gap = max_gap_right - max_gap_left;
-        for (++it1, ++it2; it2 != boost::end(sorted_range); ++it1, ++it2)
-        {
-            Value gap = geometry::get<0>(*it2) - geometry::get<0>(*it1);
-            if (math::larger(gap, max_gap))
-            {
-                max_gap_left = geometry::get<0>(*it1);
-                max_gap_right = geometry::get<0>(*it2);
-                max_gap = gap;
-            }
-        }
-
-        return max_gap;
-    }
-
-    template
-    <
-        typename Constants,
-        typename PointRange,
-        typename LongitudeLess,
-        typename CoordinateType
-    >
-    static inline void get_min_max_longitudes(PointRange& range,
-                                              LongitudeLess const& lon_less,
-                                              CoordinateType& lon_min,
-                                              CoordinateType& lon_max)
-    {
-        typedef typename boost::range_iterator
-            <
-                PointRange const
-            >::type iterator_type;
-
-        // compute min and max longitude values
-        std::pair<iterator_type, iterator_type> min_max_longitudes
-            = boost::minmax_element(boost::begin(range),
-                                    boost::end(range),
-                                    lon_less);
-
-        lon_min = geometry::get<0>(*min_max_longitudes.first);
-        lon_max = geometry::get<0>(*min_max_longitudes.second);
-
-        // if the longitude span is "large" compute the true maximum gap
-        if (math::larger(lon_max - lon_min, Constants::half_period()))
-        {
-            std::sort(boost::begin(range), boost::end(range), lon_less);
-
-            CoordinateType max_gap_left = 0, max_gap_right = 0;
-            CoordinateType max_gap
-                = maximum_gap(range, max_gap_left, max_gap_right);
-
-            CoordinateType complement_gap
-                = Constants::period() + lon_min - lon_max;
-
-            if (math::larger(max_gap, complement_gap))
-            {
-                lon_min = max_gap_right;
-                lon_max = max_gap_left + Constants::period();
-            }
-        }
-    }
-
-    template
-    <
-        typename Constants,
-        typename Iterator,
-        typename LatitudeLess,
-        typename CoordinateType
-    >
-    static inline void get_min_max_latitudes(Iterator const first,
-                                             Iterator const last,
-                                             LatitudeLess const& lat_less,
-                                             bool has_south_pole,
-                                             bool has_north_pole,
-                                             CoordinateType& lat_min,
-                                             CoordinateType& lat_max)
-    {
-        if (has_south_pole && has_north_pole)
-        {
-            lat_min = Constants::min_latitude();
-            lat_max = Constants::max_latitude();
-        }
-        else if (has_south_pole)
-        {
-            lat_min = Constants::min_latitude();
-            lat_max
-                = geometry::get<1>(*std::max_element(first, last, lat_less));
-        }
-        else if (has_north_pole)
-        {
-            lat_min
-                = geometry::get<1>(*std::min_element(first, last, lat_less));
-            lat_max = Constants::max_latitude();
-        }
-        else
-        {
-            std::pair<Iterator, Iterator> min_max_latitudes
-                = boost::minmax_element(first, last, lat_less);
-
-            lat_min = geometry::get<1>(*min_max_latitudes.first);
-            lat_max = geometry::get<1>(*min_max_latitudes.second);
-        }
-    }
-
-public:
-    template <typename MultiPoint, typename Box, typename Strategy>
-    static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& strategy)
-    {
-        typedef typename point_type<MultiPoint>::type point_type;
-        typedef typename coordinate_type<MultiPoint>::type coordinate_type;
-        typedef typename boost::range_iterator
-            <
-                MultiPoint const
-            >::type iterator_type;
-
-        typedef math::detail::constants_on_spheroid
-            <
-                coordinate_type,
-                typename coordinate_system<MultiPoint>::type::units
-            > constants;
-
-        if (boost::empty(multipoint))
-        {
-            initialize<Box, 0, dimension<Box>::value>::apply(mbr);
-            return;
-        }
-
-        initialize<Box, 0, 2>::apply(mbr);
-
-        if (boost::size(multipoint) == 1)
-        {
-            return dispatch::envelope
-                <
-                    typename boost::range_value<MultiPoint>::type
-                >::apply(range::front(multipoint), mbr, strategy);
-        }
-
-        // analyze the points and put the non-pole ones in the
-        // points vector
-        std::vector<point_type> points;
-        bool has_north_pole = false, has_south_pole = false;
-
-        analyze_point_coordinates<constants>(multipoint,
-                                             has_south_pole, has_north_pole,
-                                             std::back_inserter(points));
-
-        coordinate_type lon_min, lat_min, lon_max, lat_max;
-        if (points.size() == 1)
-        {
-            // we have one non-pole point and at least one pole point
-            lon_min = geometry::get<0>(range::front(points));
-            lon_max = geometry::get<0>(range::front(points));
-            lat_min = has_south_pole
-                ? constants::min_latitude()
-                : constants::max_latitude();
-            lat_max = has_north_pole
-                ? constants::max_latitude()
-                : constants::min_latitude();
-        }
-        else if (points.empty())
-        {
-            // all points are pole points
-            BOOST_GEOMETRY_ASSERT(has_south_pole || has_north_pole);
-            lon_min = coordinate_type(0);
-            lon_max = coordinate_type(0);
-            lat_min = has_south_pole
-                ? constants::min_latitude()
-                : constants::max_latitude();
-            lat_max = (has_north_pole)
-                ? constants::max_latitude()
-                : constants::min_latitude();
-        }
-        else
-        {
-            get_min_max_longitudes<constants>(points,
-                                              coordinate_less<0>(),
-                                              lon_min,
-                                              lon_max);
-
-            get_min_max_latitudes<constants>(points.begin(),
-                                             points.end(),
-                                             coordinate_less<1>(),
-                                             has_south_pole,
-                                             has_north_pole,
-                                             lat_min,
-                                             lat_max);
-        }
-
-        typedef typename helper_geometry
-            <
-                Box,
-                coordinate_type,
-                typename coordinate_system<MultiPoint>::type::units
-            >::type helper_box_type;
-
-        helper_box_type helper_mbr;
-
-        geometry::set<min_corner, 0>(helper_mbr, lon_min);
-        geometry::set<min_corner, 1>(helper_mbr, lat_min);
-        geometry::set<max_corner, 0>(helper_mbr, lon_max);
-        geometry::set<max_corner, 1>(helper_mbr, lat_max);
-
-        // now transform to output MBR (per index)
-        envelope_indexed_box_on_spheroid<min_corner, 2>::apply(helper_mbr, mbr);
-        envelope_indexed_box_on_spheroid<max_corner, 2>::apply(helper_mbr, mbr);
-
-        // compute envelope for higher coordinates
-        iterator_type it = boost::begin(multipoint);
-        envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr, strategy);
-
-        for (++it; it != boost::end(multipoint); ++it)
-        {
-            detail::expand::point_loop
-                <
-                    2, dimension<Box>::value
-                >::apply(mbr, *it, strategy);
-        }
-    }
-};
-
-
-}} // namespace detail::envelope
-#endif // DOXYGEN_NO_DETAIL
-
-
 
 #ifndef DOXYGEN_NO_DISPATCH
 namespace dispatch
 {
 
 
-template <typename MultiPoint, typename CSTag>
-struct envelope<MultiPoint, multi_point_tag, CSTag>
-    : detail::envelope::envelope_range
-{};
-
-template <typename MultiPoint>
-struct envelope<MultiPoint, multi_point_tag, spherical_equatorial_tag>
-    : detail::envelope::envelope_multipoint_on_spheroid
-{};
-
 template <typename MultiPoint>
-struct envelope<MultiPoint, multi_point_tag, geographic_tag>
-    : detail::envelope::envelope_multipoint_on_spheroid
-{};
+struct envelope<MultiPoint, multi_point_tag>
+{
+    template <typename Box, typename Strategy>
+    static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& )
+    {
+        Strategy::apply(multipoint, mbr);
+    }
+};
 
 
 } // namespace dispatch