Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
0006 
0007 // This file was modified by Oracle on 2014-2023.
0008 // Modifications copyright (c) 2014-2023, Oracle and/or its affiliates.
0009 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0010 // Contributed and/or modified by Menelaos Karavelas, 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_PERIMETER_HPP
0021 #define BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
0022 
0023 #include <boost/range/value_type.hpp>
0024 
0025 #include <boost/geometry/algorithms/length.hpp>
0026 #include <boost/geometry/algorithms/detail/calculate_null.hpp>
0027 #include <boost/geometry/algorithms/detail/calculate_sum.hpp>
0028 #include <boost/geometry/algorithms/detail/multi_sum.hpp>
0029 // #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
0030 #include <boost/geometry/algorithms/detail/visit.hpp>
0031 
0032 #include <boost/geometry/core/closure.hpp>
0033 #include <boost/geometry/core/tags.hpp>
0034 #include <boost/geometry/core/visit.hpp>
0035 
0036 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0037 #include <boost/geometry/geometries/concepts/check.hpp>
0038 
0039 #include <boost/geometry/strategies/default_length_result.hpp>
0040 #include <boost/geometry/strategies/default_strategy.hpp>
0041 #include <boost/geometry/strategies/detail.hpp>
0042 #include <boost/geometry/strategies/length/cartesian.hpp>
0043 #include <boost/geometry/strategies/length/geographic.hpp>
0044 #include <boost/geometry/strategies/length/spherical.hpp>
0045 
0046 namespace boost { namespace geometry
0047 {
0048 
0049 #ifndef DOXYGEN_NO_DISPATCH
0050 namespace dispatch
0051 {
0052 
0053 // Default perimeter is 0.0, specializations implement calculated values
0054 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0055 struct perimeter : detail::calculate_null
0056 {
0057     typedef typename default_length_result<Geometry>::type return_type;
0058 
0059     template <typename Strategy>
0060     static inline return_type apply(Geometry const& geometry, Strategy const& strategy)
0061     {
0062         return calculate_null::apply<return_type>(geometry, strategy);
0063     }
0064 };
0065 
0066 template <typename Geometry>
0067 struct perimeter<Geometry, ring_tag>
0068     : detail::length::range_length
0069         <
0070             Geometry,
0071             closure<Geometry>::value
0072         >
0073 {};
0074 
0075 template <typename Polygon>
0076 struct perimeter<Polygon, polygon_tag> : detail::calculate_polygon_sum
0077 {
0078     typedef typename default_length_result<Polygon>::type return_type;
0079     typedef detail::length::range_length
0080                 <
0081                     typename ring_type<Polygon>::type,
0082                     closure<Polygon>::value
0083                 > policy;
0084 
0085     template <typename Strategy>
0086     static inline return_type apply(Polygon const& polygon, Strategy const& strategy)
0087     {
0088         return calculate_polygon_sum::apply<return_type, policy>(polygon, strategy);
0089     }
0090 };
0091 
0092 template <typename MultiPolygon>
0093 struct perimeter<MultiPolygon, multi_polygon_tag> : detail::multi_sum
0094 {
0095     typedef typename default_length_result<MultiPolygon>::type return_type;
0096 
0097     template <typename Strategy>
0098     static inline return_type apply(MultiPolygon const& multi, Strategy const& strategy)
0099     {
0100         return multi_sum::apply
0101                <
0102                    return_type,
0103                    perimeter<typename boost::range_value<MultiPolygon>::type>
0104                >(multi, strategy);
0105     }
0106 };
0107 
0108 
0109 // box,n-sphere: to be implemented
0110 
0111 } // namespace dispatch
0112 #endif // DOXYGEN_NO_DISPATCH
0113 
0114 
0115 namespace resolve_strategy {
0116 
0117 template
0118 <
0119     typename Strategies,
0120     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategies>::value
0121 >
0122 struct perimeter
0123 {
0124     template <typename Geometry>
0125     static inline typename default_length_result<Geometry>::type
0126     apply(Geometry const& geometry, Strategies const& strategies)
0127     {
0128         return dispatch::perimeter<Geometry>::apply(geometry, strategies);
0129     }
0130 };
0131 
0132 template <typename Strategy>
0133 struct perimeter<Strategy, false>
0134 {
0135     template <typename Geometry>
0136     static inline typename default_length_result<Geometry>::type
0137     apply(Geometry const& geometry, Strategy const& strategy)
0138     {
0139         using strategies::length::services::strategy_converter;
0140         return dispatch::perimeter<Geometry>::apply(
0141                 geometry, strategy_converter<Strategy>::get(strategy));
0142     }
0143 };
0144 
0145 template <>
0146 struct perimeter<default_strategy, false>
0147 {
0148     template <typename Geometry>
0149     static inline typename default_length_result<Geometry>::type
0150     apply(Geometry const& geometry, default_strategy const&)
0151     {
0152         typedef typename strategies::length::services::default_strategy
0153             <
0154                 Geometry
0155             >::type strategies_type;
0156 
0157         return dispatch::perimeter<Geometry>::apply(geometry, strategies_type());
0158     }
0159 };
0160 
0161 } // namespace resolve_strategy
0162 
0163 
0164 namespace resolve_dynamic {
0165 
0166 template <typename Geometry, typename Tag = typename geometry::tag<Geometry>::type>
0167 struct perimeter
0168 {
0169     template <typename Strategy>
0170     static inline typename default_length_result<Geometry>::type
0171     apply(Geometry const& geometry, Strategy const& strategy)
0172     {
0173         concepts::check<Geometry const>();
0174         return resolve_strategy::perimeter<Strategy>::apply(geometry, strategy);
0175     }
0176 };
0177 
0178 template <typename Geometry>
0179 struct perimeter<Geometry, dynamic_geometry_tag>
0180 {
0181     template <typename Strategy>
0182     static inline typename default_length_result<Geometry>::type
0183     apply(Geometry const& geometry, Strategy const& strategy)
0184     {
0185         typename default_length_result<Geometry>::type result = 0;
0186         traits::visit<Geometry>::apply([&](auto const& g)
0187         {
0188             result = perimeter<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
0189         }, geometry);
0190         return result;
0191     }
0192 };
0193 
0194 template <typename Geometry>
0195 struct perimeter<Geometry, geometry_collection_tag>
0196 {
0197     template <typename Strategy>
0198     static inline typename default_length_result<Geometry>::type
0199     apply(Geometry const& geometry, Strategy const& strategy)
0200     {
0201         typename default_length_result<Geometry>::type result = 0;
0202         detail::visit_breadth_first([&](auto const& g)
0203         {
0204             result += perimeter<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
0205             return true;
0206         }, geometry);
0207         return result;
0208     }
0209 };
0210 
0211 } // namespace resolve_dynamic
0212 
0213 
0214 /*!
0215 \brief \brief_calc{perimeter}
0216 \ingroup perimeter
0217 \details The function perimeter returns the perimeter of a geometry,
0218     using the default distance-calculation-strategy
0219 \tparam Geometry \tparam_geometry
0220 \param geometry \param_geometry
0221 \return \return_calc{perimeter}
0222 
0223 \qbk{[include reference/algorithms/perimeter.qbk]}
0224 \qbk{
0225 [heading Example]
0226 [perimeter]
0227 [perimeter_output]
0228 }
0229  */
0230 template<typename Geometry>
0231 inline typename default_length_result<Geometry>::type perimeter(
0232         Geometry const& geometry)
0233 {
0234     // detail::throw_on_empty_input(geometry);
0235     return resolve_dynamic::perimeter<Geometry>::apply(geometry, default_strategy());
0236 }
0237 
0238 /*!
0239 \brief \brief_calc{perimeter} \brief_strategy
0240 \ingroup perimeter
0241 \details The function perimeter returns the perimeter of a geometry,
0242     using specified strategy
0243 \tparam Geometry \tparam_geometry
0244 \tparam Strategy \tparam_strategy{distance}
0245 \param geometry \param_geometry
0246 \param strategy strategy to be used for distance calculations.
0247 \return \return_calc{perimeter}
0248 
0249 \qbk{distinguish,with strategy}
0250 \qbk{[include reference/algorithms/perimeter.qbk]}
0251  */
0252 template<typename Geometry, typename Strategy>
0253 inline typename default_length_result<Geometry>::type perimeter(
0254         Geometry const& geometry, Strategy const& strategy)
0255 {
0256     // detail::throw_on_empty_input(geometry);
0257     return resolve_dynamic::perimeter<Geometry>::apply(geometry, strategy);
0258 }
0259 
0260 }} // namespace boost::geometry
0261 
0262 #endif // BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
0263