Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:19

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-2022 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 = typename tag<Geometry>::type
0135 >
0136 struct area : detail::calculate_null
0137 {
0138     template <typename Strategy>
0139     static inline typename area_result<Geometry, Strategy>::type
0140         apply(Geometry const& geometry, Strategy const& strategy)
0141     {
0142         return calculate_null::apply
0143             <
0144                 typename area_result<Geometry, Strategy>::type
0145             >(geometry, strategy);
0146     }
0147 };
0148 
0149 
0150 template <typename Geometry>
0151 struct area<Geometry, box_tag> : detail::area::box_area
0152 {};
0153 
0154 
0155 template <typename Ring>
0156 struct area<Ring, ring_tag>
0157     : detail::area::ring_area
0158 {};
0159 
0160 
0161 template <typename Polygon>
0162 struct area<Polygon, polygon_tag> : detail::calculate_polygon_sum
0163 {
0164     template <typename Strategy>
0165     static inline typename area_result<Polygon, Strategy>::type
0166         apply(Polygon const& polygon, Strategy const& strategy)
0167     {
0168         return calculate_polygon_sum::apply
0169             <
0170                 typename area_result<Polygon, Strategy>::type,
0171                 detail::area::ring_area
0172             >(polygon, strategy);
0173     }
0174 };
0175 
0176 
0177 template <typename MultiGeometry>
0178 struct area<MultiGeometry, multi_polygon_tag> : detail::multi_sum
0179 {
0180     template <typename Strategy>
0181     static inline typename area_result<MultiGeometry, Strategy>::type
0182     apply(MultiGeometry const& multi, Strategy const& strategy)
0183     {
0184         return multi_sum::apply
0185                <
0186                    typename area_result<MultiGeometry, Strategy>::type,
0187                    area<typename boost::range_value<MultiGeometry>::type>
0188                >(multi, strategy);
0189     }
0190 };
0191 
0192 
0193 } // namespace dispatch
0194 #endif // DOXYGEN_NO_DISPATCH
0195 
0196 
0197 namespace resolve_strategy
0198 {
0199 
0200 template
0201 <
0202     typename Strategy,
0203     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0204 >
0205 struct area
0206 {
0207     template <typename Geometry>
0208     static inline typename area_result<Geometry, Strategy>::type
0209     apply(Geometry const& geometry, Strategy const& strategy)
0210     {
0211         return dispatch::area<Geometry>::apply(geometry, strategy);
0212     }
0213 };
0214 
0215 template <typename Strategy>
0216 struct area<Strategy, false>
0217 {
0218     template <typename Geometry>
0219     static auto apply(Geometry const& geometry, Strategy const& strategy)
0220     {
0221         using strategies::area::services::strategy_converter;
0222         return dispatch::area
0223             <
0224                 Geometry
0225             >::apply(geometry, strategy_converter<Strategy>::get(strategy));
0226     }
0227 };
0228 
0229 template <>
0230 struct area<default_strategy, false>
0231 {
0232     template <typename Geometry>
0233     static inline typename area_result<Geometry>::type
0234     apply(Geometry const& geometry, default_strategy)
0235     {
0236         typedef typename strategies::area::services::default_strategy
0237             <
0238                 Geometry
0239             >::type strategy_type;
0240 
0241         return dispatch::area<Geometry>::apply(geometry, strategy_type());
0242     }
0243 };
0244 
0245 
0246 } // namespace resolve_strategy
0247 
0248 
0249 namespace resolve_dynamic
0250 {
0251 
0252 template <typename Geometry, typename Tag = typename geometry::tag<Geometry>::type>
0253 struct area
0254 {
0255     template <typename Strategy>
0256     static inline typename area_result<Geometry, Strategy>::type
0257         apply(Geometry const& geometry, Strategy const& strategy)
0258     {
0259         return resolve_strategy::area<Strategy>::apply(geometry, strategy);
0260     }
0261 };
0262 
0263 template <typename Geometry>
0264 struct area<Geometry, dynamic_geometry_tag>
0265 {
0266     template <typename Strategy>
0267     static inline typename area_result<Geometry, Strategy>::type
0268         apply(Geometry const& geometry, Strategy const& strategy)
0269     {
0270         typename area_result<Geometry, Strategy>::type result = 0;
0271         traits::visit<Geometry>::apply([&](auto const& g)
0272         {
0273             result = area<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
0274         }, geometry);
0275         return result;
0276     }
0277 };
0278 
0279 template <typename Geometry>
0280 struct area<Geometry, geometry_collection_tag>
0281 {
0282     template <typename Strategy>
0283     static inline typename area_result<Geometry, Strategy>::type
0284         apply(Geometry const& geometry, Strategy const& strategy)
0285     {
0286         typename area_result<Geometry, Strategy>::type result = 0;
0287         detail::visit_breadth_first([&](auto const& g)
0288         {
0289             result += area<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
0290             return true;
0291         }, geometry);
0292         return result;
0293     }
0294 };
0295 
0296 } // namespace resolve_dynamic
0297 
0298 
0299 /*!
0300 \brief \brief_calc{area}
0301 \ingroup area
0302 \details \details_calc{area}. \details_default_strategy
0303 
0304 The area algorithm calculates the surface area of all geometries having a surface, namely
0305 box, polygon, ring, multipolygon. The units are the square of the units used for the points
0306 defining the surface. If subject geometry is defined in meters, then area is calculated
0307 in square meters.
0308 
0309 The area calculation can be done in all three common coordinate systems, Cartesian, Spherical
0310 and Geographic as well.
0311 
0312 \tparam Geometry \tparam_geometry
0313 \param geometry \param_geometry
0314 \return \return_calc{area}
0315 
0316 \qbk{[include reference/algorithms/area.qbk]}
0317 \qbk{[heading Examples]}
0318 \qbk{[area] [area_output]}
0319 */
0320 template <typename Geometry>
0321 inline typename area_result<Geometry>::type
0322 area(Geometry const& geometry)
0323 {
0324     concepts::check<Geometry const>();
0325 
0326     // detail::throw_on_empty_input(geometry);
0327 
0328     return resolve_dynamic::area<Geometry>::apply(geometry, default_strategy());
0329 }
0330 
0331 /*!
0332 \brief \brief_calc{area} \brief_strategy
0333 \ingroup area
0334 \details \details_calc{area} \brief_strategy. \details_strategy_reasons
0335 \tparam Geometry \tparam_geometry
0336 \tparam Strategy \tparam_strategy{Area}
0337 \param geometry \param_geometry
0338 \param strategy \param_strategy{area}
0339 \return \return_calc{area}
0340 
0341 \qbk{distinguish,with strategy}
0342 
0343 \qbk{
0344 [include reference/algorithms/area.qbk]
0345 
0346 [heading Available Strategies]
0347 \* [link geometry.reference.strategies.strategy_area_cartesian Cartesian]
0348 \* [link geometry.reference.strategies.strategy_area_spherical Spherical]
0349 \* [link geometry.reference.strategies.strategy_area_geographic Geographic]
0350 
0351 [heading Example]
0352 [area_with_strategy]
0353 [area_with_strategy_output]
0354 }
0355  */
0356 template <typename Geometry, typename Strategy>
0357 inline typename area_result<Geometry, Strategy>::type
0358 area(Geometry const& geometry, Strategy const& strategy)
0359 {
0360     concepts::check<Geometry const>();
0361 
0362     // detail::throw_on_empty_input(geometry);
0363 
0364     return resolve_dynamic::area<Geometry>::apply(geometry, strategy);
0365 }
0366 
0367 
0368 }} // namespace boost::geometry
0369 
0370 
0371 #endif // BOOST_GEOMETRY_ALGORITHMS_AREA_HPP