Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/geometry/algorithms/area.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2017-2024 Adam Wulkiewicz, Lodz, Poland.
0007 
0008 // This file was modified by Oracle on 2017-2023.
0009 // Modifications copyright (c) 2017-2023 Oracle and/or its affiliates.
0010 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0011 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0012 
0013 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0014 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0015 
0016 // Use, modification and distribution is subject to the Boost Software License,
0017 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0018 // http://www.boost.org/LICENSE_1_0.txt)
0019 
0020 #ifndef BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
0021 #define BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
0022 
0023 #include <boost/core/ignore_unused.hpp>
0024 #include <boost/range/begin.hpp>
0025 #include <boost/range/end.hpp>
0026 #include <boost/range/size.hpp>
0027 #include <boost/range/value_type.hpp>
0028 
0029 #include <boost/geometry/core/closure.hpp>
0030 #include <boost/geometry/core/exterior_ring.hpp>
0031 #include <boost/geometry/core/interior_rings.hpp>
0032 #include <boost/geometry/core/point_order.hpp>
0033 #include <boost/geometry/core/point_type.hpp>
0034 #include <boost/geometry/core/ring_type.hpp>
0035 #include <boost/geometry/core/tags.hpp>
0036 #include <boost/geometry/core/visit.hpp>
0037 
0038 #include <boost/geometry/algorithms/detail/calculate_null.hpp>
0039 #include <boost/geometry/algorithms/detail/calculate_sum.hpp>
0040 // #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
0041 #include <boost/geometry/algorithms/detail/multi_sum.hpp>
0042 #include <boost/geometry/algorithms/detail/visit.hpp>
0043 
0044 #include <boost/geometry/algorithms/area_result.hpp>
0045 #include <boost/geometry/algorithms/default_area_result.hpp>
0046 
0047 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0048 #include <boost/geometry/geometries/concepts/check.hpp>
0049 
0050 #include <boost/geometry/strategies/area/services.hpp>
0051 #include <boost/geometry/strategies/area/cartesian.hpp>
0052 #include <boost/geometry/strategies/area/geographic.hpp>
0053 #include <boost/geometry/strategies/area/spherical.hpp>
0054 #include <boost/geometry/strategies/concepts/area_concept.hpp>
0055 #include <boost/geometry/strategies/default_strategy.hpp>
0056 
0057 #include <boost/geometry/views/detail/closed_clockwise_view.hpp>
0058 
0059 
0060 namespace boost { namespace geometry
0061 {
0062 
0063 
0064 #ifndef DOXYGEN_NO_DETAIL
0065 namespace detail { namespace area
0066 {
0067 
0068 struct box_area
0069 {
0070     template <typename Box, typename Strategies>
0071     static inline auto
0072     apply(Box const& box, Strategies const& strategies)
0073     {
0074         // Currently only works for 2D Cartesian boxes
0075         assert_dimension<Box, 2>();
0076 
0077         return strategies.area(box).apply(box);
0078     }
0079 };
0080 
0081 
0082 struct ring_area
0083 {
0084     template <typename Ring, typename Strategies>
0085     static inline typename area_result<Ring, Strategies>::type
0086     apply(Ring const& ring, Strategies const& strategies)
0087     {
0088         using strategy_type = decltype(strategies.area(ring));
0089 
0090         BOOST_CONCEPT_ASSERT( (geometry::concepts::AreaStrategy<Ring, strategy_type>) );
0091         assert_dimension<Ring, 2>();
0092 
0093         // Ignore warning (because using static method sometimes) on strategy
0094         boost::ignore_unused(strategies);
0095 
0096         // An open ring has at least three points,
0097         // A closed ring has at least four points,
0098         // if not, there is no (zero) area
0099         if (boost::size(ring) < detail::minimum_ring_size<Ring>::value)
0100         {
0101             return typename area_result<Ring, Strategies>::type();
0102         }
0103 
0104         detail::closed_clockwise_view<Ring const> const view(ring);
0105         auto it = boost::begin(view);
0106         auto const end = boost::end(view);
0107 
0108         strategy_type const strategy = strategies.area(ring);
0109         typename strategy_type::template state<Ring> state;
0110 
0111         for (auto previous = it++; it != end; ++previous, ++it)
0112         {
0113             strategy.apply(*previous, *it, state);
0114         }
0115 
0116         return strategy.result(state);
0117     }
0118 };
0119 
0120 
0121 }} // namespace detail::area
0122 
0123 
0124 #endif // DOXYGEN_NO_DETAIL
0125 
0126 
0127 #ifndef DOXYGEN_NO_DISPATCH
0128 namespace dispatch
0129 {
0130 
0131 template
0132 <
0133     typename Geometry,
0134     typename Tag = tag_t<Geometry>
0135 >
0136 struct area : detail::calculate_null
0137 {
0138     template <typename Strategy>
0139     static inline auto apply(Geometry const& geometry, Strategy const& strategy)
0140     {
0141         return calculate_null::apply
0142             <
0143                 typename area_result<Geometry, Strategy>::type
0144             >(geometry, strategy);
0145     }
0146 };
0147 
0148 
0149 template <typename Geometry>
0150 struct area<Geometry, box_tag> : detail::area::box_area
0151 {};
0152 
0153 
0154 template <typename Ring>
0155 struct area<Ring, ring_tag>
0156     : detail::area::ring_area
0157 {};
0158 
0159 
0160 template <typename Polygon>
0161 struct area<Polygon, polygon_tag> : detail::calculate_polygon_sum
0162 {
0163     template <typename Strategy>
0164     static inline auto apply(Polygon const& polygon, Strategy const& strategy)
0165     {
0166         return calculate_polygon_sum::apply
0167             <
0168                 typename area_result<Polygon, Strategy>::type,
0169                 detail::area::ring_area
0170             >(polygon, strategy);
0171     }
0172 };
0173 
0174 
0175 template <typename MultiGeometry>
0176 struct area<MultiGeometry, multi_polygon_tag> : detail::multi_sum
0177 {
0178     template <typename Strategy>
0179     static inline auto apply(MultiGeometry const& multi, Strategy const& strategy)
0180     {
0181         return multi_sum::apply
0182                <
0183                    typename area_result<MultiGeometry, Strategy>::type,
0184                    area<typename boost::range_value<MultiGeometry>::type>
0185                >(multi, strategy);
0186     }
0187 };
0188 
0189 
0190 } // namespace dispatch
0191 #endif // DOXYGEN_NO_DISPATCH
0192 
0193 
0194 namespace resolve_strategy
0195 {
0196 
0197 template
0198 <
0199     typename Strategy,
0200     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0201 >
0202 struct area
0203 {
0204     template <typename Geometry>
0205     static inline auto apply(Geometry const& geometry, Strategy const& strategy)
0206     {
0207         return dispatch::area<Geometry>::apply(geometry, strategy);
0208     }
0209 };
0210 
0211 template <typename Strategy>
0212 struct area<Strategy, false>
0213 {
0214     template <typename Geometry>
0215     static auto apply(Geometry const& geometry, Strategy const& strategy)
0216     {
0217         using strategies::area::services::strategy_converter;
0218         return dispatch::area
0219             <
0220                 Geometry
0221             >::apply(geometry, strategy_converter<Strategy>::get(strategy));
0222     }
0223 };
0224 
0225 template <>
0226 struct area<default_strategy, false>
0227 {
0228     template <typename Geometry>
0229     static inline auto apply(Geometry const& geometry, default_strategy)
0230     {
0231         typedef typename strategies::area::services::default_strategy
0232             <
0233                 Geometry
0234             >::type strategy_type;
0235 
0236         return dispatch::area<Geometry>::apply(geometry, strategy_type());
0237     }
0238 };
0239 
0240 
0241 } // namespace resolve_strategy
0242 
0243 
0244 namespace resolve_dynamic
0245 {
0246 
0247 template <typename Geometry, typename Tag = geometry::tag_t<Geometry>>
0248 struct area
0249 {
0250     template <typename Strategy>
0251     static inline auto apply(Geometry const& geometry, Strategy const& strategy)
0252     {
0253         return resolve_strategy::area<Strategy>::apply(geometry, strategy);
0254     }
0255 };
0256 
0257 template <typename Geometry>
0258 struct area<Geometry, dynamic_geometry_tag>
0259 {
0260     template <typename Strategy>
0261     static inline auto apply(Geometry const& geometry, Strategy const& strategy)
0262     {
0263         typename area_result<Geometry, Strategy>::type result = 0;
0264         traits::visit<Geometry>::apply([&](auto const& g)
0265         {
0266             result = area<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
0267         }, geometry);
0268         return result;
0269     }
0270 };
0271 
0272 template <typename Geometry>
0273 struct area<Geometry, geometry_collection_tag>
0274 {
0275     template <typename Strategy>
0276     static inline auto apply(Geometry const& geometry, Strategy const& strategy)
0277     {
0278         typename area_result<Geometry, Strategy>::type result = 0;
0279         detail::visit_breadth_first([&](auto const& g)
0280         {
0281             result += area<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
0282             return true;
0283         }, geometry);
0284         return result;
0285     }
0286 };
0287 
0288 } // namespace resolve_dynamic
0289 
0290 
0291 /*!
0292 \brief \brief_calc{area}
0293 \ingroup area
0294 \details \details_calc{area}. \details_default_strategy
0295 
0296 The area algorithm calculates the surface area of all geometries having a surface, namely
0297 box, polygon, ring, multipolygon. The units are the square of the units used for the points
0298 defining the surface. If subject geometry is defined in meters, then area is calculated
0299 in square meters.
0300 
0301 The area calculation can be done in all three common coordinate systems, Cartesian, Spherical
0302 and Geographic as well.
0303 
0304 \tparam Geometry \tparam_geometry
0305 \param geometry \param_geometry
0306 \return \return_calc{area}
0307 
0308 \qbk{[include reference/algorithms/area.qbk]}
0309 \qbk{[heading Examples]}
0310 \qbk{[area] [area_output]}
0311 */
0312 template <typename Geometry>
0313 inline auto area(Geometry const& geometry)
0314 {
0315     concepts::check<Geometry const>();
0316 
0317     // detail::throw_on_empty_input(geometry);
0318 
0319     return resolve_dynamic::area<Geometry>::apply(geometry, default_strategy());
0320 }
0321 
0322 /*!
0323 \brief \brief_calc{area} \brief_strategy
0324 \ingroup area
0325 \details \details_calc{area} \brief_strategy. \details_strategy_reasons
0326 \tparam Geometry \tparam_geometry
0327 \tparam Strategy \tparam_strategy{Area}
0328 \param geometry \param_geometry
0329 \param strategy \param_strategy{area}
0330 \return \return_calc{area}
0331 
0332 \qbk{distinguish,with strategy}
0333 
0334 \qbk{
0335 [include reference/algorithms/area.qbk]
0336 
0337 [heading Available Strategies]
0338 \* [link geometry.reference.strategies.strategy_area_cartesian Cartesian]
0339 \* [link geometry.reference.strategies.strategy_area_spherical Spherical]
0340 \* [link geometry.reference.strategies.strategy_area_geographic Geographic]
0341 
0342 [heading Example]
0343 [area_with_strategy]
0344 [area_with_strategy_output]
0345 }
0346  */
0347 template <typename Geometry, typename Strategy>
0348 inline auto area(Geometry const& geometry, Strategy const& strategy)
0349 {
0350     concepts::check<Geometry const>();
0351 
0352     // detail::throw_on_empty_input(geometry);
0353 
0354     return resolve_dynamic::area<Geometry>::apply(geometry, strategy);
0355 }
0356 
0357 
0358 }} // namespace boost::geometry
0359 
0360 
0361 #endif // BOOST_GEOMETRY_ALGORITHMS_AREA_HPP