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