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
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
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
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
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
0094 boost::ignore_unused(strategies);
0095
0096
0097
0098
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 }}
0122
0123
0124 #endif
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 }
0191 #endif
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 }
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 }
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 template <typename Geometry>
0313 inline auto area(Geometry const& geometry)
0314 {
0315 concepts::check<Geometry const>();
0316
0317
0318
0319 return resolve_dynamic::area<Geometry>::apply(geometry, default_strategy());
0320 }
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
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
0353
0354 return resolve_dynamic::area<Geometry>::apply(geometry, strategy);
0355 }
0356
0357
0358 }}
0359
0360
0361 #endif