File indexing completed on 2025-07-11 08:11:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RECALCULATE_HPP
0017 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RECALCULATE_HPP
0018
0019
0020 #include <cstddef>
0021
0022 #include <boost/concept/requires.hpp>
0023 #include <boost/concept_check.hpp>
0024 #include <boost/range/begin.hpp>
0025 #include <boost/range/end.hpp>
0026 #include <boost/range/size.hpp>
0027
0028 #include <boost/geometry/arithmetic/arithmetic.hpp>
0029 #include <boost/geometry/algorithms/append.hpp>
0030 #include <boost/geometry/algorithms/clear.hpp>
0031 #include <boost/geometry/core/access.hpp>
0032 #include <boost/geometry/core/interior_rings.hpp>
0033 #include <boost/geometry/core/exterior_ring.hpp>
0034 #include <boost/geometry/core/tags.hpp>
0035
0036 #include <boost/geometry/geometries/concepts/check.hpp>
0037
0038
0039 namespace boost { namespace geometry
0040 {
0041
0042 #ifndef DOXYGEN_NO_DETAIL
0043 namespace detail { namespace recalculate
0044 {
0045
0046 template <std::size_t Dimension>
0047 struct recalculate_point
0048 {
0049 template <typename Point1, typename Point2, typename Strategy>
0050 static inline void apply(Point1& point1, Point2 const& point2, Strategy const& strategy)
0051 {
0052 std::size_t const dim = Dimension - 1;
0053 geometry::set<dim>(point1, strategy.template apply<dim>(geometry::get<dim>(point2)));
0054 recalculate_point<dim>::apply(point1, point2, strategy);
0055 }
0056 };
0057
0058 template <>
0059 struct recalculate_point<0>
0060 {
0061 template <typename Point1, typename Point2, typename Strategy>
0062 static inline void apply(Point1&, Point2 const&, Strategy const&)
0063 {
0064 }
0065 };
0066
0067
0068 template <std::size_t Dimension>
0069 struct recalculate_indexed
0070 {
0071 template <typename Geometry1, typename Geometry2, typename Strategy>
0072 static inline void apply(Geometry1& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
0073 {
0074
0075 static std::size_t const dim = Dimension - 1;
0076 geometry::set<0, dim>(geometry1, strategy.template apply<dim>(geometry::get<0, dim>(geometry2)));
0077 geometry::set<1, dim>(geometry1, strategy.template apply<dim>(geometry::get<1, dim>(geometry2)));
0078 recalculate_indexed<dim>::apply(geometry1, geometry2, strategy);
0079 }
0080 };
0081
0082 template <>
0083 struct recalculate_indexed<0>
0084 {
0085
0086 template <typename Geometry1, typename Geometry2, typename Strategy>
0087 static inline void apply(Geometry1& , Geometry2 const& , Strategy const& )
0088 {
0089 }
0090 };
0091
0092 struct range_to_range
0093 {
0094 template
0095 <
0096 typename Range1,
0097 typename Range2,
0098 typename Strategy
0099 >
0100 static inline void apply(Range1& destination, Range2 const& source,
0101 Strategy const& strategy)
0102 {
0103 typedef typename geometry::point_type<Range2>::type point_type;
0104 typedef recalculate_point<geometry::dimension<point_type>::value> per_point;
0105 geometry::clear(destination);
0106
0107 for (auto const& source_point : source)
0108 {
0109 point_type p;
0110 per_point::apply(p, source_point, strategy);
0111 geometry::append(destination, p);
0112 }
0113 }
0114 };
0115
0116 struct polygon_to_polygon
0117 {
0118 private:
0119 template
0120 <
0121 typename IteratorIn,
0122 typename IteratorOut,
0123 typename Strategy
0124 >
0125 static inline void iterate(IteratorIn begin, IteratorIn end,
0126 IteratorOut it_out,
0127 Strategy const& strategy)
0128 {
0129 for (IteratorIn it_in = begin; it_in != end; ++it_in, ++it_out)
0130 {
0131 range_to_range::apply(*it_out, *it_in, strategy);
0132 }
0133 }
0134
0135 template
0136 <
0137 typename InteriorRingsOut,
0138 typename InteriorRingsIn,
0139 typename Strategy
0140 >
0141 static inline void apply_interior_rings(
0142 InteriorRingsOut& interior_rings_out,
0143 InteriorRingsIn const& interior_rings_in,
0144 Strategy const& strategy)
0145 {
0146 traits::resize<InteriorRingsOut>::apply(interior_rings_out,
0147 boost::size(interior_rings_in));
0148
0149 iterate(
0150 boost::begin(interior_rings_in), boost::end(interior_rings_in),
0151 boost::begin(interior_rings_out),
0152 strategy);
0153 }
0154
0155 public:
0156 template
0157 <
0158 typename Polygon1,
0159 typename Polygon2,
0160 typename Strategy
0161 >
0162 static inline void apply(Polygon1& destination, Polygon2 const& source,
0163 Strategy const& strategy)
0164 {
0165 range_to_range::apply(geometry::exterior_ring(destination),
0166 geometry::exterior_ring(source), strategy);
0167
0168 apply_interior_rings(geometry::interior_rings(destination),
0169 geometry::interior_rings(source), strategy);
0170 }
0171 };
0172
0173 }}
0174 #endif
0175
0176 #ifndef DOXYGEN_NO_DISPATCH
0177 namespace dispatch
0178 {
0179
0180 template
0181 <
0182 typename Geometry1,
0183 typename Geometry2,
0184 typename Tag1 = typename geometry::tag<Geometry1>::type,
0185 typename Tag2 = typename geometry::tag<Geometry2>::type
0186 >
0187 struct recalculate : not_implemented<Tag1, Tag2>
0188 {};
0189
0190 template <typename Point1, typename Point2>
0191 struct recalculate<Point1, Point2, point_tag, point_tag>
0192 : detail::recalculate::recalculate_point<geometry::dimension<Point1>::value>
0193 {};
0194
0195 template <typename Box1, typename Box2>
0196 struct recalculate<Box1, Box2, box_tag, box_tag>
0197 : detail::recalculate::recalculate_indexed<geometry::dimension<Box1>::value>
0198 {};
0199
0200 template <typename Segment1, typename Segment2>
0201 struct recalculate<Segment1, Segment2, segment_tag, segment_tag>
0202 : detail::recalculate::recalculate_indexed<geometry::dimension<Segment1>::value>
0203 {};
0204
0205 template <typename Polygon1, typename Polygon2>
0206 struct recalculate<Polygon1, Polygon2, polygon_tag, polygon_tag>
0207 : detail::recalculate::polygon_to_polygon
0208 {};
0209
0210 }
0211 #endif
0212
0213
0214
0215 template <typename Geometry1, typename Geometry2, typename Strategy>
0216 inline void recalculate(Geometry1& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
0217 {
0218 concepts::check<Geometry1>();
0219 concepts::check<Geometry2 const>();
0220
0221
0222
0223 dispatch::recalculate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
0224 }
0225
0226
0227 }}
0228
0229
0230 #endif