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_LENGTH_HPP
0021 #define BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP
0022 
0023 #include <boost/range/begin.hpp>
0024 #include <boost/range/end.hpp>
0025 #include <boost/range/value_type.hpp>
0026 
0027 #include "boost/geometry/algorithms/detail/assign_indexed_point.hpp"
0028 #include <boost/geometry/algorithms/detail/calculate_null.hpp>
0029 #include <boost/geometry/algorithms/detail/dummy_geometries.hpp>
0030 #include <boost/geometry/algorithms/detail/multi_sum.hpp>
0031 // #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
0032 #include <boost/geometry/algorithms/detail/visit.hpp>
0033 
0034 #include <boost/geometry/core/closure.hpp>
0035 #include <boost/geometry/core/tag.hpp>
0036 #include <boost/geometry/core/tags.hpp>
0037 #include <boost/geometry/core/visit.hpp>
0038 
0039 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0040 #include <boost/geometry/geometries/concepts/check.hpp>
0041 
0042 #include <boost/geometry/strategies/default_strategy.hpp>
0043 #include <boost/geometry/strategies/default_length_result.hpp> // TODO: Move to algorithms
0044 #include <boost/geometry/strategies/detail.hpp>
0045 #include <boost/geometry/strategies/length/cartesian.hpp>
0046 #include <boost/geometry/strategies/length/geographic.hpp>
0047 #include <boost/geometry/strategies/length/spherical.hpp>
0048 
0049 #include <boost/geometry/views/closeable_view.hpp>
0050 
0051 namespace boost { namespace geometry
0052 {
0053 
0054 
0055 #ifndef DOXYGEN_NO_DETAIL
0056 namespace detail { namespace length
0057 {
0058 
0059 
0060 template<typename Segment>
0061 struct segment_length
0062 {
0063     template <typename Strategies>
0064     static inline typename default_length_result<Segment>::type
0065     apply(Segment const& segment, Strategies const& strategies)
0066     {
0067         typedef typename point_type<Segment>::type point_type;
0068         point_type p1, p2;
0069         geometry::detail::assign_point_from_index<0>(segment, p1);
0070         geometry::detail::assign_point_from_index<1>(segment, p2);
0071         return strategies.distance(p1, p2).apply(p1, p2);
0072     }
0073 };
0074 
0075 /*!
0076 \brief Internal, calculates length of a linestring using iterator pairs and
0077     specified strategy
0078 \note for_each could be used here, now that point_type is changed by boost
0079     range iterator
0080 */
0081 template<typename Range, closure_selector Closure>
0082 struct range_length
0083 {
0084     typedef typename default_length_result<Range>::type return_type;
0085 
0086     template <typename Strategies>
0087     static inline return_type
0088     apply(Range const& range, Strategies const& strategies)
0089     {
0090         return_type sum = return_type();
0091         detail::closed_view<Range const> const view(range);
0092         auto it = boost::begin(view);
0093         auto const end = boost::end(view);
0094         if (it != end)
0095         {
0096             auto const strategy = strategies.distance(dummy_point(), dummy_point());
0097 
0098             for(auto previous = it++; it != end; ++previous, ++it)
0099             {
0100                 // Add point-point distance using the return type belonging
0101                 // to strategy
0102                 sum += strategy.apply(*previous, *it);
0103             }
0104         }
0105 
0106         return sum;
0107     }
0108 };
0109 
0110 
0111 }} // namespace detail::length
0112 #endif // DOXYGEN_NO_DETAIL
0113 
0114 
0115 #ifndef DOXYGEN_NO_DISPATCH
0116 namespace dispatch
0117 {
0118 
0119 
0120 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0121 struct length : detail::calculate_null
0122 {
0123     typedef typename default_length_result<Geometry>::type return_type;
0124 
0125     template <typename Strategy>
0126     static inline return_type apply(Geometry const& geometry, Strategy const& strategy)
0127     {
0128         return calculate_null::apply<return_type>(geometry, strategy);
0129     }
0130 };
0131 
0132 
0133 template <typename Geometry>
0134 struct length<Geometry, linestring_tag>
0135     : detail::length::range_length<Geometry, closed>
0136 {};
0137 
0138 
0139 // RING: length is currently 0; it might be argued that it is the "perimeter"
0140 
0141 
0142 template <typename Geometry>
0143 struct length<Geometry, segment_tag>
0144     : detail::length::segment_length<Geometry>
0145 {};
0146 
0147 
0148 template <typename MultiLinestring>
0149 struct length<MultiLinestring, multi_linestring_tag> : detail::multi_sum
0150 {
0151     template <typename Strategy>
0152     static inline typename default_length_result<MultiLinestring>::type
0153     apply(MultiLinestring const& multi, Strategy const& strategy)
0154     {
0155         return multi_sum::apply
0156                <
0157                    typename default_length_result<MultiLinestring>::type,
0158                    detail::length::range_length
0159                    <
0160                        typename boost::range_value<MultiLinestring>::type,
0161                        closed // no need to close it explicitly
0162                    >
0163                >(multi, strategy);
0164 
0165     }
0166 };
0167 
0168 
0169 } // namespace dispatch
0170 #endif // DOXYGEN_NO_DISPATCH
0171 
0172 
0173 namespace resolve_strategy {
0174 
0175 template
0176 <
0177     typename Strategies,
0178     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategies>::value
0179 >
0180 struct length
0181 {
0182     template <typename Geometry>
0183     static inline typename default_length_result<Geometry>::type
0184     apply(Geometry const& geometry, Strategies const& strategies)
0185     {
0186         return dispatch::length<Geometry>::apply(geometry, strategies);
0187     }
0188 };
0189 
0190 template <typename Strategy>
0191 struct length<Strategy, false>
0192 {
0193     template <typename Geometry>
0194     static inline typename default_length_result<Geometry>::type
0195     apply(Geometry const& geometry, Strategy const& strategy)
0196     {
0197         using strategies::length::services::strategy_converter;
0198         return dispatch::length<Geometry>::apply(
0199                 geometry, strategy_converter<Strategy>::get(strategy));
0200     }
0201 };
0202 
0203 template <>
0204 struct length<default_strategy, false>
0205 {
0206     template <typename Geometry>
0207     static inline typename default_length_result<Geometry>::type
0208     apply(Geometry const& geometry, default_strategy const&)
0209     {
0210         typedef typename strategies::length::services::default_strategy
0211             <
0212                 Geometry
0213             >::type strategies_type;
0214 
0215         return dispatch::length<Geometry>::apply(geometry, strategies_type());
0216     }
0217 };
0218 
0219 } // namespace resolve_strategy
0220 
0221 
0222 namespace resolve_dynamic {
0223 
0224 template <typename Geometry, typename Tag = typename geometry::tag<Geometry>::type>
0225 struct length
0226 {
0227     template <typename Strategy>
0228     static inline typename default_length_result<Geometry>::type
0229     apply(Geometry const& geometry, Strategy const& strategy)
0230     {
0231         return resolve_strategy::length<Strategy>::apply(geometry, strategy);
0232     }
0233 };
0234 
0235 template <typename Geometry>
0236 struct length<Geometry, dynamic_geometry_tag>
0237 {
0238     template <typename Strategy>
0239     static inline typename default_length_result<Geometry>::type
0240         apply(Geometry const& geometry, Strategy const& strategy)
0241     {
0242         typename default_length_result<Geometry>::type result = 0;
0243         traits::visit<Geometry>::apply([&](auto const& g)
0244         {
0245             result = length<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
0246         }, geometry);
0247         return result;
0248     }
0249 };
0250 
0251 template <typename Geometry>
0252 struct length<Geometry, geometry_collection_tag>
0253 {
0254     template <typename Strategy>
0255     static inline typename default_length_result<Geometry>::type
0256         apply(Geometry const& geometry, Strategy const& strategy)
0257     {
0258         typename default_length_result<Geometry>::type result = 0;
0259         detail::visit_breadth_first([&](auto const& g)
0260         {
0261             result += length<util::remove_cref_t<decltype(g)>>::apply(g, strategy);
0262             return true;
0263         }, geometry);
0264         return result;
0265     }
0266 };
0267 
0268 } // namespace resolve_dynamic
0269 
0270 
0271 /*!
0272 \brief \brief_calc{length}
0273 \ingroup length
0274 \details \details_calc{length, length (the sum of distances between consecutive points)}. \details_default_strategy
0275 \tparam Geometry \tparam_geometry
0276 \param geometry \param_geometry
0277 \return \return_calc{length}
0278 
0279 \qbk{[include reference/algorithms/length.qbk]}
0280 \qbk{[length] [length_output]}
0281  */
0282 template<typename Geometry>
0283 inline typename default_length_result<Geometry>::type
0284 length(Geometry const& geometry)
0285 {
0286     concepts::check<Geometry const>();
0287 
0288     // detail::throw_on_empty_input(geometry);
0289 
0290     return resolve_dynamic::length<Geometry>::apply(geometry, default_strategy());
0291 }
0292 
0293 
0294 /*!
0295 \brief \brief_calc{length} \brief_strategy
0296 \ingroup length
0297 \details \details_calc{length, length (the sum of distances between consecutive points)} \brief_strategy. \details_strategy_reasons
0298 \tparam Geometry \tparam_geometry
0299 \tparam Strategy \tparam_strategy{distance}
0300 \param geometry \param_geometry
0301 \param strategy \param_strategy{distance}
0302 \return \return_calc{length}
0303 
0304 \qbk{distinguish,with strategy}
0305 \qbk{[include reference/algorithms/length.qbk]}
0306 \qbk{[length_with_strategy] [length_with_strategy_output]}
0307  */
0308 template<typename Geometry, typename Strategy>
0309 inline typename default_length_result<Geometry>::type
0310 length(Geometry const& geometry, Strategy const& strategy)
0311 {
0312     concepts::check<Geometry const>();
0313 
0314     // detail::throw_on_empty_input(geometry);
0315 
0316     return resolve_dynamic::length<Geometry>::apply(geometry, strategy);
0317 }
0318 
0319 
0320 }} // namespace boost::geometry
0321 
0322 #endif // BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP