File indexing completed on 2025-01-18 09:35:19
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 = 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 }
0194 #endif
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 }
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 }
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
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
0327
0328 return resolve_dynamic::area<Geometry>::apply(geometry, default_strategy());
0329 }
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
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
0363
0364 return resolve_dynamic::area<Geometry>::apply(geometry, strategy);
0365 }
0366
0367
0368 }}
0369
0370
0371 #endif