Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@16
|
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
Chris@16
|
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
Chris@16
|
6
|
Chris@16
|
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
Chris@16
|
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
Chris@16
|
9
|
Chris@16
|
10 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
12 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
13
|
Chris@16
|
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
|
Chris@16
|
15 #define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
|
Chris@16
|
16
|
Chris@16
|
17
|
Chris@16
|
18 #include <cstddef>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/numeric/conversion/cast.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 #include <boost/geometry/algorithms/not_implemented.hpp>
|
Chris@16
|
23 #include <boost/geometry/core/coordinate_dimension.hpp>
|
Chris@16
|
24 #include <boost/geometry/geometries/concepts/check.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 #include <boost/geometry/util/select_coordinate_type.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 #include <boost/geometry/strategies/compare.hpp>
|
Chris@16
|
29 #include <boost/geometry/policies/compare.hpp>
|
Chris@16
|
30
|
Chris@16
|
31
|
Chris@16
|
32 namespace boost { namespace geometry
|
Chris@16
|
33 {
|
Chris@16
|
34
|
Chris@16
|
35 #ifndef DOXYGEN_NO_DETAIL
|
Chris@16
|
36 namespace detail { namespace expand
|
Chris@16
|
37 {
|
Chris@16
|
38
|
Chris@16
|
39
|
Chris@16
|
40 template
|
Chris@16
|
41 <
|
Chris@16
|
42 typename StrategyLess, typename StrategyGreater,
|
Chris@16
|
43 std::size_t Dimension, std::size_t DimensionCount
|
Chris@16
|
44 >
|
Chris@16
|
45 struct point_loop
|
Chris@16
|
46 {
|
Chris@16
|
47 template <typename Box, typename Point>
|
Chris@16
|
48 static inline void apply(Box& box, Point const& source)
|
Chris@16
|
49 {
|
Chris@16
|
50 typedef typename strategy::compare::detail::select_strategy
|
Chris@16
|
51 <
|
Chris@16
|
52 StrategyLess, 1, Point, Dimension
|
Chris@16
|
53 >::type less_type;
|
Chris@16
|
54
|
Chris@16
|
55 typedef typename strategy::compare::detail::select_strategy
|
Chris@16
|
56 <
|
Chris@16
|
57 StrategyGreater, -1, Point, Dimension
|
Chris@16
|
58 >::type greater_type;
|
Chris@16
|
59
|
Chris@16
|
60 typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
|
Chris@16
|
61
|
Chris@16
|
62 less_type less;
|
Chris@16
|
63 greater_type greater;
|
Chris@16
|
64
|
Chris@16
|
65 coordinate_type const coord = get<Dimension>(source);
|
Chris@16
|
66
|
Chris@16
|
67 if (less(coord, get<min_corner, Dimension>(box)))
|
Chris@16
|
68 {
|
Chris@16
|
69 set<min_corner, Dimension>(box, coord);
|
Chris@16
|
70 }
|
Chris@16
|
71
|
Chris@16
|
72 if (greater(coord, get<max_corner, Dimension>(box)))
|
Chris@16
|
73 {
|
Chris@16
|
74 set<max_corner, Dimension>(box, coord);
|
Chris@16
|
75 }
|
Chris@16
|
76
|
Chris@16
|
77 point_loop
|
Chris@16
|
78 <
|
Chris@16
|
79 StrategyLess, StrategyGreater,
|
Chris@16
|
80 Dimension + 1, DimensionCount
|
Chris@16
|
81 >::apply(box, source);
|
Chris@16
|
82 }
|
Chris@16
|
83 };
|
Chris@16
|
84
|
Chris@16
|
85
|
Chris@16
|
86 template
|
Chris@16
|
87 <
|
Chris@16
|
88 typename StrategyLess, typename StrategyGreater,
|
Chris@16
|
89 std::size_t DimensionCount
|
Chris@16
|
90 >
|
Chris@16
|
91 struct point_loop
|
Chris@16
|
92 <
|
Chris@16
|
93 StrategyLess, StrategyGreater,
|
Chris@16
|
94 DimensionCount, DimensionCount
|
Chris@16
|
95 >
|
Chris@16
|
96 {
|
Chris@16
|
97 template <typename Box, typename Point>
|
Chris@16
|
98 static inline void apply(Box&, Point const&) {}
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101
|
Chris@16
|
102 template
|
Chris@16
|
103 <
|
Chris@16
|
104 typename StrategyLess, typename StrategyGreater,
|
Chris@16
|
105 std::size_t Index,
|
Chris@16
|
106 std::size_t Dimension, std::size_t DimensionCount
|
Chris@16
|
107 >
|
Chris@16
|
108 struct indexed_loop
|
Chris@16
|
109 {
|
Chris@16
|
110 template <typename Box, typename Geometry>
|
Chris@16
|
111 static inline void apply(Box& box, Geometry const& source)
|
Chris@16
|
112 {
|
Chris@16
|
113 typedef typename strategy::compare::detail::select_strategy
|
Chris@16
|
114 <
|
Chris@16
|
115 StrategyLess, 1, Box, Dimension
|
Chris@16
|
116 >::type less_type;
|
Chris@16
|
117
|
Chris@16
|
118 typedef typename strategy::compare::detail::select_strategy
|
Chris@16
|
119 <
|
Chris@16
|
120 StrategyGreater, -1, Box, Dimension
|
Chris@16
|
121 >::type greater_type;
|
Chris@16
|
122
|
Chris@16
|
123 typedef typename select_coordinate_type
|
Chris@16
|
124 <
|
Chris@16
|
125 Box,
|
Chris@16
|
126 Geometry
|
Chris@16
|
127 >::type coordinate_type;
|
Chris@16
|
128
|
Chris@16
|
129 less_type less;
|
Chris@16
|
130 greater_type greater;
|
Chris@16
|
131
|
Chris@16
|
132 coordinate_type const coord = get<Index, Dimension>(source);
|
Chris@16
|
133
|
Chris@16
|
134 if (less(coord, get<min_corner, Dimension>(box)))
|
Chris@16
|
135 {
|
Chris@16
|
136 set<min_corner, Dimension>(box, coord);
|
Chris@16
|
137 }
|
Chris@16
|
138
|
Chris@16
|
139 if (greater(coord, get<max_corner, Dimension>(box)))
|
Chris@16
|
140 {
|
Chris@16
|
141 set<max_corner, Dimension>(box, coord);
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@16
|
144 indexed_loop
|
Chris@16
|
145 <
|
Chris@16
|
146 StrategyLess, StrategyGreater,
|
Chris@16
|
147 Index, Dimension + 1, DimensionCount
|
Chris@16
|
148 >::apply(box, source);
|
Chris@16
|
149 }
|
Chris@16
|
150 };
|
Chris@16
|
151
|
Chris@16
|
152
|
Chris@16
|
153 template
|
Chris@16
|
154 <
|
Chris@16
|
155 typename StrategyLess, typename StrategyGreater,
|
Chris@16
|
156 std::size_t Index, std::size_t DimensionCount
|
Chris@16
|
157 >
|
Chris@16
|
158 struct indexed_loop
|
Chris@16
|
159 <
|
Chris@16
|
160 StrategyLess, StrategyGreater,
|
Chris@16
|
161 Index, DimensionCount, DimensionCount
|
Chris@16
|
162 >
|
Chris@16
|
163 {
|
Chris@16
|
164 template <typename Box, typename Geometry>
|
Chris@16
|
165 static inline void apply(Box&, Geometry const&) {}
|
Chris@16
|
166 };
|
Chris@16
|
167
|
Chris@16
|
168
|
Chris@16
|
169
|
Chris@16
|
170 // Changes a box such that the other box is also contained by the box
|
Chris@16
|
171 template
|
Chris@16
|
172 <
|
Chris@16
|
173 typename StrategyLess, typename StrategyGreater
|
Chris@16
|
174 >
|
Chris@16
|
175 struct expand_indexed
|
Chris@16
|
176 {
|
Chris@16
|
177 template <typename Box, typename Geometry>
|
Chris@16
|
178 static inline void apply(Box& box, Geometry const& geometry)
|
Chris@16
|
179 {
|
Chris@16
|
180 indexed_loop
|
Chris@16
|
181 <
|
Chris@16
|
182 StrategyLess, StrategyGreater,
|
Chris@16
|
183 0, 0, dimension<Geometry>::type::value
|
Chris@16
|
184 >::apply(box, geometry);
|
Chris@16
|
185
|
Chris@16
|
186 indexed_loop
|
Chris@16
|
187 <
|
Chris@16
|
188 StrategyLess, StrategyGreater,
|
Chris@16
|
189 1, 0, dimension<Geometry>::type::value
|
Chris@16
|
190 >::apply(box, geometry);
|
Chris@16
|
191 }
|
Chris@16
|
192 };
|
Chris@16
|
193
|
Chris@16
|
194 }} // namespace detail::expand
|
Chris@16
|
195 #endif // DOXYGEN_NO_DETAIL
|
Chris@16
|
196
|
Chris@16
|
197 #ifndef DOXYGEN_NO_DISPATCH
|
Chris@16
|
198 namespace dispatch
|
Chris@16
|
199 {
|
Chris@16
|
200
|
Chris@16
|
201 template
|
Chris@16
|
202 <
|
Chris@16
|
203 typename GeometryOut, typename Geometry,
|
Chris@16
|
204 typename StrategyLess = strategy::compare::default_strategy,
|
Chris@16
|
205 typename StrategyGreater = strategy::compare::default_strategy,
|
Chris@16
|
206 typename TagOut = typename tag<GeometryOut>::type,
|
Chris@16
|
207 typename Tag = typename tag<Geometry>::type
|
Chris@16
|
208 >
|
Chris@16
|
209 struct expand: not_implemented<TagOut, Tag>
|
Chris@16
|
210 {};
|
Chris@16
|
211
|
Chris@16
|
212
|
Chris@16
|
213 // Box + point -> new box containing also point
|
Chris@16
|
214 template
|
Chris@16
|
215 <
|
Chris@16
|
216 typename BoxOut, typename Point,
|
Chris@16
|
217 typename StrategyLess, typename StrategyGreater
|
Chris@16
|
218 >
|
Chris@16
|
219 struct expand<BoxOut, Point, StrategyLess, StrategyGreater, box_tag, point_tag>
|
Chris@16
|
220 : detail::expand::point_loop
|
Chris@16
|
221 <
|
Chris@16
|
222 StrategyLess, StrategyGreater,
|
Chris@16
|
223 0, dimension<Point>::type::value
|
Chris@16
|
224 >
|
Chris@16
|
225 {};
|
Chris@16
|
226
|
Chris@16
|
227
|
Chris@16
|
228 // Box + box -> new box containing two input boxes
|
Chris@16
|
229 template
|
Chris@16
|
230 <
|
Chris@16
|
231 typename BoxOut, typename BoxIn,
|
Chris@16
|
232 typename StrategyLess, typename StrategyGreater
|
Chris@16
|
233 >
|
Chris@16
|
234 struct expand<BoxOut, BoxIn, StrategyLess, StrategyGreater, box_tag, box_tag>
|
Chris@16
|
235 : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
|
Chris@16
|
236 {};
|
Chris@16
|
237
|
Chris@16
|
238 template
|
Chris@16
|
239 <
|
Chris@16
|
240 typename Box, typename Segment,
|
Chris@16
|
241 typename StrategyLess, typename StrategyGreater
|
Chris@16
|
242 >
|
Chris@16
|
243 struct expand<Box, Segment, StrategyLess, StrategyGreater, box_tag, segment_tag>
|
Chris@16
|
244 : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
|
Chris@16
|
245 {};
|
Chris@16
|
246
|
Chris@16
|
247
|
Chris@16
|
248 } // namespace dispatch
|
Chris@16
|
249 #endif // DOXYGEN_NO_DISPATCH
|
Chris@16
|
250
|
Chris@16
|
251
|
Chris@16
|
252 /***
|
Chris@16
|
253 *!
|
Chris@16
|
254 \brief Expands a box using the extend (envelope) of another geometry (box, point)
|
Chris@16
|
255 \ingroup expand
|
Chris@16
|
256 \tparam Box type of the box
|
Chris@16
|
257 \tparam Geometry of second geometry, to be expanded with the box
|
Chris@16
|
258 \param box box to expand another geometry with, might be changed
|
Chris@16
|
259 \param geometry other geometry
|
Chris@16
|
260 \param strategy_less
|
Chris@16
|
261 \param strategy_greater
|
Chris@16
|
262 \note Strategy is currently ignored
|
Chris@16
|
263 *
|
Chris@16
|
264 template
|
Chris@16
|
265 <
|
Chris@16
|
266 typename Box, typename Geometry,
|
Chris@16
|
267 typename StrategyLess, typename StrategyGreater
|
Chris@16
|
268 >
|
Chris@16
|
269 inline void expand(Box& box, Geometry const& geometry,
|
Chris@16
|
270 StrategyLess const& strategy_less,
|
Chris@16
|
271 StrategyGreater const& strategy_greater)
|
Chris@16
|
272 {
|
Chris@16
|
273 concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
|
Chris@16
|
274
|
Chris@16
|
275 dispatch::expand<Box, Geometry>::apply(box, geometry);
|
Chris@16
|
276 }
|
Chris@16
|
277 ***/
|
Chris@16
|
278
|
Chris@16
|
279
|
Chris@16
|
280 /*!
|
Chris@16
|
281 \brief Expands a box using the bounding box (envelope) of another geometry (box, point)
|
Chris@16
|
282 \ingroup expand
|
Chris@16
|
283 \tparam Box type of the box
|
Chris@16
|
284 \tparam Geometry \tparam_geometry
|
Chris@16
|
285 \param box box to be expanded using another geometry, mutable
|
Chris@16
|
286 \param geometry \param_geometry geometry which envelope (bounding box) will be added to the box
|
Chris@16
|
287
|
Chris@16
|
288 \qbk{[include reference/algorithms/expand.qbk]}
|
Chris@16
|
289 */
|
Chris@16
|
290 template <typename Box, typename Geometry>
|
Chris@16
|
291 inline void expand(Box& box, Geometry const& geometry)
|
Chris@16
|
292 {
|
Chris@16
|
293 concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
|
Chris@16
|
294
|
Chris@16
|
295 dispatch::expand<Box, Geometry>::apply(box, geometry);
|
Chris@16
|
296 }
|
Chris@16
|
297
|
Chris@16
|
298 }} // namespace boost::geometry
|
Chris@16
|
299
|
Chris@16
|
300 #endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
|