1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. 6 7 // This file was modified by Oracle on 2015, 2016. 8 // Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. 9 10 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle 11 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 12 13 // Distributed under the Boost Software License, Version 1.0. 14 // (See accompanying file LICENSE_1_0.txt or copy at 15 // http://www.boost.org/LICENSE_1_0.txt) 16 17 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP 18 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP 19 20 #include <cstddef> 21 22 #include <boost/geometry/core/cs.hpp> 23 #include <boost/geometry/core/coordinate_dimension.hpp> 24 #include <boost/geometry/core/coordinate_system.hpp> 25 #include <boost/geometry/core/tags.hpp> 26 27 #include <boost/geometry/views/detail/indexed_point_view.hpp> 28 29 #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp> 30 #include <boost/geometry/algorithms/detail/normalize.hpp> 31 #include <boost/geometry/algorithms/detail/envelope/transform_units.hpp> 32 33 #include <boost/geometry/algorithms/dispatch/envelope.hpp> 34 35 36 namespace boost { namespace geometry 37 { 38 39 #ifndef DOXYGEN_NO_DETAIL 40 namespace detail { namespace envelope 41 { 42 43 44 template 45 < 46 std::size_t Index, 47 std::size_t Dimension, 48 std::size_t DimensionCount 49 > 50 struct envelope_indexed_box 51 { 52 template <typename BoxIn, typename BoxOut> applyboost::geometry::detail::envelope::envelope_indexed_box53 static inline void apply(BoxIn const& box_in, BoxOut& mbr) 54 { 55 detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in); 56 detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr); 57 58 detail::conversion::point_to_point 59 < 60 detail::indexed_point_view<BoxIn const, Index>, 61 detail::indexed_point_view<BoxOut, Index>, 62 Dimension, 63 DimensionCount 64 >::apply(box_in_corner, mbr_corner); 65 } 66 }; 67 68 template 69 < 70 std::size_t Index, 71 std::size_t DimensionCount 72 > 73 struct envelope_indexed_box_on_spheroid 74 { 75 template <typename BoxIn, typename BoxOut> applyboost::geometry::detail::envelope::envelope_indexed_box_on_spheroid76 static inline void apply(BoxIn const& box_in, BoxOut& mbr) 77 { 78 // transform() does not work with boxes of dimension higher 79 // than 2; to account for such boxes we transform the min/max 80 // points of the boxes using the indexed_point_view 81 detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in); 82 detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr); 83 84 // first transform the units 85 transform_units(box_in_corner, mbr_corner); 86 87 // now transform the remaining coordinates 88 detail::conversion::point_to_point 89 < 90 detail::indexed_point_view<BoxIn const, Index>, 91 detail::indexed_point_view<BoxOut, Index>, 92 2, 93 DimensionCount 94 >::apply(box_in_corner, mbr_corner); 95 } 96 }; 97 98 99 struct envelope_box 100 { 101 template<typename BoxIn, typename BoxOut, typename Strategy> applyboost::geometry::detail::envelope::envelope_box102 static inline void apply(BoxIn const& box_in, 103 BoxOut& mbr, 104 Strategy const&) 105 { 106 envelope_indexed_box 107 < 108 min_corner, 0, dimension<BoxIn>::value 109 >::apply(box_in, mbr); 110 111 envelope_indexed_box 112 < 113 max_corner, 0, dimension<BoxIn>::value 114 >::apply(box_in, mbr); 115 } 116 }; 117 118 119 struct envelope_box_on_spheroid 120 { 121 template <typename BoxIn, typename BoxOut, typename Strategy> applyboost::geometry::detail::envelope::envelope_box_on_spheroid122 static inline void apply(BoxIn const& box_in, 123 BoxOut& mbr, 124 Strategy const&) 125 { 126 BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in); 127 128 envelope_indexed_box_on_spheroid 129 < 130 min_corner, dimension<BoxIn>::value 131 >::apply(box_in_normalized, mbr); 132 133 envelope_indexed_box_on_spheroid 134 < 135 max_corner, dimension<BoxIn>::value 136 >::apply(box_in_normalized, mbr); 137 } 138 }; 139 140 141 }} // namespace detail::envelope 142 #endif // DOXYGEN_NO_DETAIL 143 144 #ifndef DOXYGEN_NO_DISPATCH 145 namespace dispatch 146 { 147 148 149 template <typename Box, typename CS_Tag> 150 struct envelope<Box, box_tag, CS_Tag> 151 : detail::envelope::envelope_box 152 {}; 153 154 155 template <typename Box> 156 struct envelope<Box, box_tag, spherical_equatorial_tag> 157 : detail::envelope::envelope_box_on_spheroid 158 {}; 159 160 161 template <typename Box> 162 struct envelope<Box, box_tag, geographic_tag> 163 : detail::envelope::envelope_box_on_spheroid 164 {}; 165 166 167 } // namespace dispatch 168 #endif // DOXYGEN_NO_DISPATCH 169 170 }} // namespace boost::geometry 171 172 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP 173