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