]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/algorithms/area.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / area.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
11fdf7f2 6// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
7c673cae 7
11fdf7f2
TL
8// This file was modified by Oracle on 2017, 2018.
9// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
b32b8144
FG
10// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11
7c673cae
FG
12// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
14
15// Use, modification and distribution is subject to the Boost Software License,
16// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17// http://www.boost.org/LICENSE_1_0.txt)
18
19#ifndef BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
20#define BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
21
22#include <boost/concept_check.hpp>
7c673cae
FG
23#include <boost/range/functions.hpp>
24#include <boost/range/metafunctions.hpp>
25
26#include <boost/variant/apply_visitor.hpp>
27#include <boost/variant/static_visitor.hpp>
28#include <boost/variant/variant_fwd.hpp>
29
30#include <boost/geometry/core/closure.hpp>
31#include <boost/geometry/core/exterior_ring.hpp>
32#include <boost/geometry/core/interior_rings.hpp>
33#include <boost/geometry/core/point_order.hpp>
34#include <boost/geometry/core/point_type.hpp>
35#include <boost/geometry/core/ring_type.hpp>
36#include <boost/geometry/core/tags.hpp>
37
38#include <boost/geometry/geometries/concepts/check.hpp>
39
40#include <boost/geometry/algorithms/detail/calculate_null.hpp>
41#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
42// #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
43#include <boost/geometry/algorithms/detail/multi_sum.hpp>
44
45#include <boost/geometry/strategies/area.hpp>
11fdf7f2 46#include <boost/geometry/strategies/area_result.hpp>
7c673cae 47#include <boost/geometry/strategies/default_area_result.hpp>
11fdf7f2 48#include <boost/geometry/strategies/default_strategy.hpp>
7c673cae
FG
49
50#include <boost/geometry/strategies/concepts/area_concept.hpp>
51
52#include <boost/geometry/util/math.hpp>
53#include <boost/geometry/util/order_as_direction.hpp>
54#include <boost/geometry/views/closeable_view.hpp>
55#include <boost/geometry/views/reversible_view.hpp>
56
57
58namespace boost { namespace geometry
59{
60
11fdf7f2 61
7c673cae
FG
62#ifndef DOXYGEN_NO_DETAIL
63namespace detail { namespace area
64{
65
66struct box_area
67{
68 template <typename Box, typename Strategy>
69 static inline typename coordinate_type<Box>::type
70 apply(Box const& box, Strategy const&)
71 {
72 // Currently only works for 2D Cartesian boxes
73 assert_dimension<Box, 2>();
74
75 return (get<max_corner, 0>(box) - get<min_corner, 0>(box))
76 * (get<max_corner, 1>(box) - get<min_corner, 1>(box));
77 }
78};
79
80
81template
82<
83 iterate_direction Direction,
84 closure_selector Closure
85>
86struct ring_area
87{
88 template <typename Ring, typename Strategy>
11fdf7f2 89 static inline typename area_result<Ring, Strategy>::type
7c673cae
FG
90 apply(Ring const& ring, Strategy const& strategy)
91 {
11fdf7f2 92 BOOST_CONCEPT_ASSERT( (geometry::concepts::AreaStrategy<Ring, Strategy>) );
7c673cae
FG
93 assert_dimension<Ring, 2>();
94
95 // Ignore warning (because using static method sometimes) on strategy
96 boost::ignore_unused_variable_warning(strategy);
97
98 // An open ring has at least three points,
99 // A closed ring has at least four points,
100 // if not, there is no (zero) area
101 if (boost::size(ring)
102 < core_detail::closure::minimum_ring_size<Closure>::value)
103 {
11fdf7f2 104 return typename area_result<Ring, Strategy>::type();
7c673cae
FG
105 }
106
107 typedef typename reversible_view<Ring const, Direction>::type rview_type;
108 typedef typename closeable_view
109 <
110 rview_type const, Closure
111 >::type view_type;
112 typedef typename boost::range_iterator<view_type const>::type iterator_type;
113
114 rview_type rview(ring);
115 view_type view(rview);
11fdf7f2 116 typename Strategy::template state<Ring> state;
7c673cae
FG
117 iterator_type it = boost::begin(view);
118 iterator_type end = boost::end(view);
119
120 for (iterator_type previous = it++;
121 it != end;
122 ++previous, ++it)
123 {
124 strategy.apply(*previous, *it, state);
125 }
126
127 return strategy.result(state);
128 }
129};
130
131
132}} // namespace detail::area
133
134
135#endif // DOXYGEN_NO_DETAIL
136
137
138#ifndef DOXYGEN_NO_DISPATCH
139namespace dispatch
140{
141
142template
143<
144 typename Geometry,
145 typename Tag = typename tag<Geometry>::type
146>
147struct area : detail::calculate_null
148{
149 template <typename Strategy>
11fdf7f2
TL
150 static inline typename area_result<Geometry, Strategy>::type
151 apply(Geometry const& geometry, Strategy const& strategy)
7c673cae 152 {
11fdf7f2
TL
153 return calculate_null::apply
154 <
155 typename area_result<Geometry, Strategy>::type
156 >(geometry, strategy);
7c673cae
FG
157 }
158};
159
160
161template <typename Geometry>
162struct area<Geometry, box_tag> : detail::area::box_area
163{};
164
165
166template <typename Ring>
167struct area<Ring, ring_tag>
168 : detail::area::ring_area
169 <
170 order_as_direction<geometry::point_order<Ring>::value>::value,
171 geometry::closure<Ring>::value
172 >
173{};
174
175
176template <typename Polygon>
177struct area<Polygon, polygon_tag> : detail::calculate_polygon_sum
178{
179 template <typename Strategy>
11fdf7f2
TL
180 static inline typename area_result<Polygon, Strategy>::type
181 apply(Polygon const& polygon, Strategy const& strategy)
7c673cae
FG
182 {
183 return calculate_polygon_sum::apply<
11fdf7f2 184 typename area_result<Polygon, Strategy>::type,
7c673cae
FG
185 detail::area::ring_area
186 <
187 order_as_direction<geometry::point_order<Polygon>::value>::value,
188 geometry::closure<Polygon>::value
189 >
190 >(polygon, strategy);
191 }
192};
193
194
195template <typename MultiGeometry>
196struct area<MultiGeometry, multi_polygon_tag> : detail::multi_sum
197{
198 template <typename Strategy>
11fdf7f2 199 static inline typename area_result<MultiGeometry, Strategy>::type
7c673cae
FG
200 apply(MultiGeometry const& multi, Strategy const& strategy)
201 {
202 return multi_sum::apply
203 <
11fdf7f2 204 typename area_result<MultiGeometry, Strategy>::type,
7c673cae
FG
205 area<typename boost::range_value<MultiGeometry>::type>
206 >(multi, strategy);
207 }
208};
209
210
211} // namespace dispatch
212#endif // DOXYGEN_NO_DISPATCH
213
214
11fdf7f2
TL
215namespace resolve_strategy
216{
217
218struct area
219{
220 template <typename Geometry, typename Strategy>
221 static inline typename area_result<Geometry, Strategy>::type
222 apply(Geometry const& geometry, Strategy const& strategy)
223 {
224 return dispatch::area<Geometry>::apply(geometry, strategy);
225 }
226
227 template <typename Geometry>
228 static inline typename area_result<Geometry>::type
229 apply(Geometry const& geometry, default_strategy)
230 {
231 typedef typename strategy::area::services::default_strategy
232 <
233 typename cs_tag<Geometry>::type
234 >::type strategy_type;
235
236 return dispatch::area<Geometry>::apply(geometry, strategy_type());
237 }
238};
239
240
241} // namespace resolve_strategy
242
243
244namespace resolve_variant
245{
7c673cae
FG
246
247template <typename Geometry>
248struct area
249{
250 template <typename Strategy>
11fdf7f2
TL
251 static inline typename area_result<Geometry, Strategy>::type
252 apply(Geometry const& geometry, Strategy const& strategy)
7c673cae 253 {
11fdf7f2 254 return resolve_strategy::area::apply(geometry, strategy);
7c673cae
FG
255 }
256};
257
258template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
259struct area<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
260{
11fdf7f2
TL
261 typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
262
7c673cae 263 template <typename Strategy>
11fdf7f2
TL
264 struct visitor
265 : boost::static_visitor<typename area_result<variant_type, Strategy>::type>
7c673cae
FG
266 {
267 Strategy const& m_strategy;
268
269 visitor(Strategy const& strategy): m_strategy(strategy) {}
270
271 template <typename Geometry>
11fdf7f2
TL
272 typename area_result<variant_type, Strategy>::type
273 operator()(Geometry const& geometry) const
7c673cae
FG
274 {
275 return area<Geometry>::apply(geometry, m_strategy);
276 }
277 };
278
279 template <typename Strategy>
11fdf7f2
TL
280 static inline typename area_result<variant_type, Strategy>::type
281 apply(variant_type const& geometry,
7c673cae
FG
282 Strategy const& strategy)
283 {
284 return boost::apply_visitor(visitor<Strategy>(strategy), geometry);
285 }
286};
287
288} // namespace resolve_variant
289
290
291/*!
292\brief \brief_calc{area}
293\ingroup area
294\details \details_calc{area}. \details_default_strategy
295
296The area algorithm calculates the surface area of all geometries having a surface, namely
297box, polygon, ring, multipolygon. The units are the square of the units used for the points
298defining the surface. If subject geometry is defined in meters, then area is calculated
299in square meters.
300
301The area calculation can be done in all three common coordinate systems, Cartesian, Spherical
302and Geographic as well.
303
304\tparam Geometry \tparam_geometry
305\param geometry \param_geometry
306\return \return_calc{area}
307
308\qbk{[include reference/algorithms/area.qbk]}
309\qbk{[heading Examples]}
310\qbk{[area] [area_output]}
311*/
312template <typename Geometry>
11fdf7f2
TL
313inline typename area_result<Geometry>::type
314area(Geometry const& geometry)
7c673cae
FG
315{
316 concepts::check<Geometry const>();
317
7c673cae
FG
318 // detail::throw_on_empty_input(geometry);
319
11fdf7f2 320 return resolve_variant::area<Geometry>::apply(geometry, default_strategy());
7c673cae
FG
321}
322
323/*!
324\brief \brief_calc{area} \brief_strategy
325\ingroup area
326\details \details_calc{area} \brief_strategy. \details_strategy_reasons
327\tparam Geometry \tparam_geometry
328\tparam Strategy \tparam_strategy{Area}
329\param geometry \param_geometry
330\param strategy \param_strategy{area}
331\return \return_calc{area}
332
333\qbk{distinguish,with strategy}
334
335\qbk{
336[include reference/algorithms/area.qbk]
337
11fdf7f2
TL
338[heading Available Strategies]
339\* [link geometry.reference.strategies.strategy_area_cartesian Cartesian]
340\* [link geometry.reference.strategies.strategy_area_spherical Spherical]
341\* [link geometry.reference.strategies.strategy_area_geographic Geographic]
342
7c673cae
FG
343[heading Example]
344[area_with_strategy]
345[area_with_strategy_output]
7c673cae
FG
346}
347 */
348template <typename Geometry, typename Strategy>
11fdf7f2
TL
349inline typename area_result<Geometry, Strategy>::type
350area(Geometry const& geometry, Strategy const& strategy)
7c673cae
FG
351{
352 concepts::check<Geometry const>();
353
354 // detail::throw_on_empty_input(geometry);
355
356 return resolve_variant::area<Geometry>::apply(geometry, strategy);
357}
358
359
360}} // namespace boost::geometry
361
362
363#endif // BOOST_GEOMETRY_ALGORITHMS_AREA_HPP