comparison DEPENDENCIES/generic/include/boost/geometry/algorithms/area.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
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.
6
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
9
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
13
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
16
17 #include <boost/concept_check.hpp>
18 #include <boost/mpl/if.hpp>
19 #include <boost/range/functions.hpp>
20 #include <boost/range/metafunctions.hpp>
21 #include <boost/variant/static_visitor.hpp>
22 #include <boost/variant/apply_visitor.hpp>
23 #include <boost/variant/variant_fwd.hpp>
24
25 #include <boost/geometry/core/closure.hpp>
26 #include <boost/geometry/core/exterior_ring.hpp>
27 #include <boost/geometry/core/interior_rings.hpp>
28 #include <boost/geometry/core/point_order.hpp>
29 #include <boost/geometry/core/ring_type.hpp>
30
31 #include <boost/geometry/geometries/concepts/check.hpp>
32
33 #include <boost/geometry/algorithms/detail/calculate_null.hpp>
34 #include <boost/geometry/algorithms/detail/calculate_sum.hpp>
35 // #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
36
37 #include <boost/geometry/strategies/area.hpp>
38 #include <boost/geometry/strategies/default_area_result.hpp>
39
40 #include <boost/geometry/strategies/concepts/area_concept.hpp>
41
42 #include <boost/geometry/util/math.hpp>
43 #include <boost/geometry/util/order_as_direction.hpp>
44 #include <boost/geometry/views/closeable_view.hpp>
45 #include <boost/geometry/views/reversible_view.hpp>
46
47
48 namespace boost { namespace geometry
49 {
50
51 #ifndef DOXYGEN_NO_DETAIL
52 namespace detail { namespace area
53 {
54
55 struct box_area
56 {
57 template <typename Box, typename Strategy>
58 static inline typename coordinate_type<Box>::type
59 apply(Box const& box, Strategy const&)
60 {
61 // Currently only works for 2D Cartesian boxes
62 assert_dimension<Box, 2>();
63
64 return (get<max_corner, 0>(box) - get<min_corner, 0>(box))
65 * (get<max_corner, 1>(box) - get<min_corner, 1>(box));
66 }
67 };
68
69
70 template
71 <
72 iterate_direction Direction,
73 closure_selector Closure
74 >
75 struct ring_area
76 {
77 template <typename Ring, typename Strategy>
78 static inline typename Strategy::return_type
79 apply(Ring const& ring, Strategy const& strategy)
80 {
81 BOOST_CONCEPT_ASSERT( (geometry::concept::AreaStrategy<Strategy>) );
82 assert_dimension<Ring, 2>();
83
84 // Ignore warning (because using static method sometimes) on strategy
85 boost::ignore_unused_variable_warning(strategy);
86
87 // An open ring has at least three points,
88 // A closed ring has at least four points,
89 // if not, there is no (zero) area
90 if (int(boost::size(ring))
91 < core_detail::closure::minimum_ring_size<Closure>::value)
92 {
93 return typename Strategy::return_type();
94 }
95
96 typedef typename reversible_view<Ring const, Direction>::type rview_type;
97 typedef typename closeable_view
98 <
99 rview_type const, Closure
100 >::type view_type;
101 typedef typename boost::range_iterator<view_type const>::type iterator_type;
102
103 rview_type rview(ring);
104 view_type view(rview);
105 typename Strategy::state_type state;
106 iterator_type it = boost::begin(view);
107 iterator_type end = boost::end(view);
108
109 for (iterator_type previous = it++;
110 it != end;
111 ++previous, ++it)
112 {
113 strategy.apply(*previous, *it, state);
114 }
115
116 return strategy.result(state);
117 }
118 };
119
120
121 }} // namespace detail::area
122
123
124 #endif // DOXYGEN_NO_DETAIL
125
126
127 #ifndef DOXYGEN_NO_DISPATCH
128 namespace dispatch
129 {
130
131 template
132 <
133 typename Geometry,
134 typename Tag = typename tag<Geometry>::type
135 >
136 struct area : detail::calculate_null
137 {
138 template <typename Strategy>
139 static inline typename Strategy::return_type apply(Geometry const& geometry, Strategy const& strategy)
140 {
141 return calculate_null::apply<typename Strategy::return_type>(geometry, strategy);
142 }
143 };
144
145
146 template <typename Geometry>
147 struct area<Geometry, box_tag> : detail::area::box_area
148 {};
149
150
151 template <typename Ring>
152 struct area<Ring, ring_tag>
153 : detail::area::ring_area
154 <
155 order_as_direction<geometry::point_order<Ring>::value>::value,
156 geometry::closure<Ring>::value
157 >
158 {};
159
160
161 template <typename Polygon>
162 struct area<Polygon, polygon_tag> : detail::calculate_polygon_sum
163 {
164 template <typename Strategy>
165 static inline typename Strategy::return_type apply(Polygon const& polygon, Strategy const& strategy)
166 {
167 return calculate_polygon_sum::apply<
168 typename Strategy::return_type,
169 detail::area::ring_area
170 <
171 order_as_direction<geometry::point_order<Polygon>::value>::value,
172 geometry::closure<Polygon>::value
173 >
174 >(polygon, strategy);
175 }
176 };
177
178
179 template <typename Geometry>
180 struct devarianted_area
181 {
182 template <typename Strategy>
183 static inline typename Strategy::return_type apply(Geometry const& geometry,
184 Strategy const& strategy)
185 {
186 return area<Geometry>::apply(geometry, strategy);
187 }
188 };
189
190 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
191 struct devarianted_area<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
192 {
193 template <typename Strategy>
194 struct visitor: boost::static_visitor<typename Strategy::return_type>
195 {
196 Strategy const& m_strategy;
197
198 visitor(Strategy const& strategy): m_strategy(strategy) {}
199
200 template <typename Geometry>
201 typename Strategy::return_type operator()(Geometry const& geometry) const
202 {
203 return devarianted_area<Geometry>::apply(geometry, m_strategy);
204 }
205 };
206
207 template <typename Strategy>
208 static inline typename Strategy::return_type
209 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
210 Strategy const& strategy)
211 {
212 return boost::apply_visitor(visitor<Strategy>(strategy), geometry);
213 }
214 };
215
216
217 } // namespace dispatch
218 #endif // DOXYGEN_NO_DISPATCH
219
220
221
222 /*!
223 \brief \brief_calc{area}
224 \ingroup area
225 \details \details_calc{area}. \details_default_strategy
226
227 The area algorithm calculates the surface area of all geometries having a surface, namely
228 box, polygon, ring, multipolygon. The units are the square of the units used for the points
229 defining the surface. If subject geometry is defined in meters, then area is calculated
230 in square meters.
231
232 The area calculation can be done in all three common coordinate systems, Cartesian, Spherical
233 and Geographic as well.
234
235 \tparam Geometry \tparam_geometry
236 \param geometry \param_geometry
237 \return \return_calc{area}
238
239 \qbk{[include reference/algorithms/area.qbk]}
240 \qbk{[heading Examples]}
241 \qbk{[area] [area_output]}
242 */
243 template <typename Geometry>
244 inline typename default_area_result<Geometry>::type area(Geometry const& geometry)
245 {
246 concept::check<Geometry const>();
247
248 typedef typename point_type<Geometry>::type point_type;
249 typedef typename strategy::area::services::default_strategy
250 <
251 typename cs_tag<point_type>::type,
252 point_type
253 >::type strategy_type;
254
255 // detail::throw_on_empty_input(geometry);
256
257 return dispatch::devarianted_area<Geometry>::apply(geometry, strategy_type());
258 }
259
260 /*!
261 \brief \brief_calc{area} \brief_strategy
262 \ingroup area
263 \details \details_calc{area} \brief_strategy. \details_strategy_reasons
264 \tparam Geometry \tparam_geometry
265 \tparam Strategy \tparam_strategy{Area}
266 \param geometry \param_geometry
267 \param strategy \param_strategy{area}
268 \return \return_calc{area}
269
270 \qbk{distinguish,with strategy}
271
272 \qbk{
273 [include reference/algorithms/area.qbk]
274
275 [heading Example]
276 [area_with_strategy]
277 [area_with_strategy_output]
278
279 [heading Available Strategies]
280 \* [link geometry.reference.strategies.strategy_area_surveyor Surveyor (cartesian)]
281 \* [link geometry.reference.strategies.strategy_area_huiller Huiller (spherical)]
282 }
283 */
284 template <typename Geometry, typename Strategy>
285 inline typename Strategy::return_type area(
286 Geometry const& geometry, Strategy const& strategy)
287 {
288 concept::check<Geometry const>();
289
290 // detail::throw_on_empty_input(geometry);
291
292 return dispatch::devarianted_area<Geometry>::apply(geometry, strategy);
293 }
294
295
296 }} // namespace boost::geometry
297
298
299 #endif // BOOST_GEOMETRY_ALGORITHMS_AREA_HPP