annotate DEPENDENCIES/generic/include/boost/geometry/algorithms/area.hpp @ 133:4acb5d8d80b6 tip

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