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_APPEND_HPP
0021 #define BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
0022
0023
0024 #include <boost/range/begin.hpp>
0025 #include <boost/range/end.hpp>
0026 #include <boost/range/value_type.hpp>
0027
0028 #include <boost/geometry/algorithms/num_interior_rings.hpp>
0029 #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
0030 #include <boost/geometry/algorithms/detail/signed_size_type.hpp>
0031 #include <boost/geometry/core/mutable_range.hpp>
0032 #include <boost/geometry/core/point_type.hpp>
0033 #include <boost/geometry/core/tags.hpp>
0034 #include <boost/geometry/core/visit.hpp>
0035 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // for backward compatibility
0036 #include <boost/geometry/geometries/concepts/check.hpp>
0037 #include <boost/geometry/util/range.hpp>
0038
0039
0040 namespace boost { namespace geometry
0041 {
0042
0043
0044 #ifndef DOXYGEN_NO_DETAIL
0045 namespace detail { namespace append
0046 {
0047
0048 struct append_no_action
0049 {
0050 template <typename Geometry, typename Point>
0051 static inline void apply(Geometry& , Point const& ,
0052 signed_size_type = -1, signed_size_type = 0)
0053 {
0054 }
0055 };
0056
0057 struct to_range_point
0058 {
0059 template <typename Geometry, typename Point>
0060 static inline void apply(Geometry& geometry, Point const& point,
0061 signed_size_type = -1, signed_size_type = 0)
0062 {
0063 typename geometry::point_type<Geometry>::type copy;
0064 geometry::detail::conversion::convert_point_to_point(point, copy);
0065 traits::push_back<Geometry>::apply(geometry, copy);
0066 }
0067 };
0068
0069
0070 struct to_range_range
0071 {
0072 template <typename Geometry, typename Range>
0073 static inline void apply(Geometry& geometry, Range const& range,
0074 signed_size_type = -1, signed_size_type = 0)
0075 {
0076 using point_type = typename boost::range_value<Range>::type;
0077
0078 auto const end = boost::end(range);
0079 for (auto it = boost::begin(range); it != end; ++it)
0080 {
0081 to_range_point::apply<Geometry, point_type>(geometry, *it);
0082 }
0083 }
0084 };
0085
0086
0087 struct to_polygon_point
0088 {
0089 template <typename Polygon, typename Point>
0090 static inline void apply(Polygon& polygon, Point const& point,
0091 signed_size_type ring_index, signed_size_type = 0)
0092 {
0093 using ring_type = typename ring_type<Polygon>::type;
0094
0095 if (ring_index == -1)
0096 {
0097 auto&& ext_ring = exterior_ring(polygon);
0098 to_range_point::apply<ring_type, Point>(ext_ring, point);
0099 }
0100 else if (ring_index < signed_size_type(num_interior_rings(polygon)))
0101 {
0102 auto&& int_rings = interior_rings(polygon);
0103 to_range_point::apply<ring_type, Point>(range::at(int_rings, ring_index), point);
0104 }
0105 }
0106 };
0107
0108
0109 struct to_polygon_range
0110 {
0111 template <typename Polygon, typename Range>
0112 static inline void apply(Polygon& polygon, Range const& range,
0113 signed_size_type ring_index, signed_size_type = 0)
0114 {
0115 using ring_type = typename ring_type<Polygon>::type;
0116 using exterior_ring_type = typename ring_return_type<Polygon>::type;
0117 using interior_ring_range_type = typename interior_return_type<Polygon>::type;
0118
0119 if (ring_index == -1)
0120 {
0121 exterior_ring_type ext_ring = exterior_ring(polygon);
0122 to_range_range::apply<ring_type, Range>(ext_ring, range);
0123 }
0124 else if (ring_index < signed_size_type(num_interior_rings(polygon)))
0125 {
0126 interior_ring_range_type int_rings = interior_rings(polygon);
0127 to_range_range::apply<ring_type, Range>(range::at(int_rings, ring_index), range);
0128 }
0129 }
0130 };
0131
0132
0133 template <typename Policy>
0134 struct to_multigeometry
0135 {
0136 template <typename MultiGeometry, typename RangeOrPoint>
0137 static inline void apply(MultiGeometry& multigeometry,
0138 RangeOrPoint const& range_or_point,
0139 signed_size_type ring_index, signed_size_type multi_index)
0140 {
0141 Policy::template apply
0142 <
0143 typename boost::range_value<MultiGeometry>::type,
0144 RangeOrPoint
0145 >(range::at(multigeometry, multi_index), range_or_point, ring_index);
0146 }
0147 };
0148
0149
0150 }}
0151 #endif
0152
0153
0154 #ifndef DOXYGEN_NO_DISPATCH
0155 namespace dispatch
0156 {
0157
0158 template
0159 <
0160 typename Geometry,
0161 typename RangeOrPoint,
0162 typename Tag = typename geometry::tag<Geometry>::type,
0163 typename OtherTag = typename geometry::tag<RangeOrPoint>::type
0164 >
0165 struct append
0166 : detail::append::append_no_action
0167 {};
0168
0169 template <typename Geometry, typename Point>
0170 struct append<Geometry, Point, linestring_tag, point_tag>
0171 : detail::append::to_range_point
0172 {};
0173
0174 template <typename Geometry, typename Point>
0175 struct append<Geometry, Point, ring_tag, point_tag>
0176 : detail::append::to_range_point
0177 {};
0178
0179 template <typename Polygon, typename Point>
0180 struct append<Polygon, Point, polygon_tag, point_tag>
0181 : detail::append::to_polygon_point
0182 {};
0183
0184 template <typename Geometry, typename Range, typename RangeTag>
0185 struct append<Geometry, Range, linestring_tag, RangeTag>
0186 : detail::append::to_range_range
0187 {};
0188
0189 template <typename Geometry, typename Range, typename RangeTag>
0190 struct append<Geometry, Range, ring_tag, RangeTag>
0191 : detail::append::to_range_range
0192 {};
0193
0194 template <typename Polygon, typename Range, typename RangeTag>
0195 struct append<Polygon, Range, polygon_tag, RangeTag>
0196 : detail::append::to_polygon_range
0197 {};
0198
0199
0200 template <typename Geometry, typename Point>
0201 struct append<Geometry, Point, multi_point_tag, point_tag>
0202 : detail::append::to_range_point
0203 {};
0204
0205 template <typename Geometry, typename Range, typename RangeTag>
0206 struct append<Geometry, Range, multi_point_tag, RangeTag>
0207 : detail::append::to_range_range
0208 {};
0209
0210 template <typename MultiGeometry, typename Point>
0211 struct append<MultiGeometry, Point, multi_linestring_tag, point_tag>
0212 : detail::append::to_multigeometry<detail::append::to_range_point>
0213 {};
0214
0215 template <typename MultiGeometry, typename Range, typename RangeTag>
0216 struct append<MultiGeometry, Range, multi_linestring_tag, RangeTag>
0217 : detail::append::to_multigeometry<detail::append::to_range_range>
0218 {};
0219
0220 template <typename MultiGeometry, typename Point>
0221 struct append<MultiGeometry, Point, multi_polygon_tag, point_tag>
0222 : detail::append::to_multigeometry<detail::append::to_polygon_point>
0223 {};
0224
0225 template <typename MultiGeometry, typename Range, typename RangeTag>
0226 struct append<MultiGeometry, Range, multi_polygon_tag, RangeTag>
0227 : detail::append::to_multigeometry<detail::append::to_polygon_range>
0228 {};
0229
0230
0231 template <typename Geometry, typename RangeOrPoint, typename OtherTag>
0232 struct append<Geometry, RangeOrPoint, dynamic_geometry_tag, OtherTag>
0233 {
0234 static inline void apply(Geometry& geometry,
0235 RangeOrPoint const& range_or_point,
0236 signed_size_type ring_index, signed_size_type multi_index)
0237 {
0238 traits::visit<Geometry>::apply([&](auto & g)
0239 {
0240 append
0241 <
0242 std::remove_reference_t<decltype(g)>, RangeOrPoint
0243 >::apply(g, range_or_point, ring_index, multi_index);
0244 }, geometry);
0245 }
0246 };
0247
0248
0249
0250
0251 }
0252 #endif
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 template <typename Geometry, typename RangeOrPoint>
0270 inline void append(Geometry& geometry, RangeOrPoint const& range_or_point,
0271 signed_size_type ring_index = -1, signed_size_type multi_index = 0)
0272 {
0273 concepts::check<Geometry>();
0274
0275 dispatch::append
0276 <
0277 Geometry, RangeOrPoint
0278 >::apply(geometry, range_or_point, ring_index, multi_index);
0279 }
0280
0281
0282 }}
0283
0284
0285 #endif