• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

boostorg / geometry / 20212

28 Jul 2023 09:16AM UTC coverage: 94.211% (-0.2%) from 94.458%
20212

push

circle-ci

vissarion
Merge branch 'develop'

39303 of 41718 relevant lines covered (94.21%)

1319371.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.62
include/boost/geometry/algorithms/append.hpp
1
// Boost.Geometry (aka GGL, Generic Geometry Library)
2

3
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
4
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
5
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
6

7
// This file was modified by Oracle on 2014-2023.
8
// Modifications copyright (c) 2014-2023, Oracle and/or its affiliates.
9
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
10
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
11
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12

13
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15

16
// Use, modification and distribution is subject to the Boost Software License,
17
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18
// http://www.boost.org/LICENSE_1_0.txt)
19

20
#ifndef BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
21
#define BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
22

23

24
#include <boost/range/begin.hpp>
25
#include <boost/range/end.hpp>
26
#include <boost/range/value_type.hpp>
27

28
#include <boost/geometry/algorithms/num_interior_rings.hpp>
29
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
30
#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
31
#include <boost/geometry/core/mutable_range.hpp>
32
#include <boost/geometry/core/point_type.hpp>
33
#include <boost/geometry/core/tags.hpp>
34
#include <boost/geometry/core/visit.hpp>
35
#include <boost/geometry/geometries/adapted/boost_variant.hpp> // for backward compatibility
36
#include <boost/geometry/geometries/concepts/check.hpp>
37
#include <boost/geometry/util/range.hpp>
38

39

40
namespace boost { namespace geometry
41
{
42

43

44
#ifndef DOXYGEN_NO_DETAIL
45
namespace detail { namespace append
46
{
47

48
struct append_no_action
49
{
50
    template <typename Geometry, typename Point>
51
    static inline void apply(Geometry& , Point const& ,
48✔
52
                             signed_size_type = -1, signed_size_type = 0)
53
    {
54
    }
48✔
55
};
56

57
struct to_range_point
58
{
59
    template <typename Geometry, typename Point>
60
    static inline void apply(Geometry& geometry, Point const& point,
265,108✔
61
                             signed_size_type = -1, signed_size_type = 0)
62
    {
63
        typename geometry::point_type<Geometry>::type copy;
1,529✔
64
        geometry::detail::conversion::convert_point_to_point(point, copy);
265,108✔
65
        traits::push_back<Geometry>::apply(geometry, copy);
265,108✔
66
    }
265,108✔
67
};
68

69

70
struct to_range_range
71
{
72
    template <typename Geometry, typename Range>
73
    static inline void apply(Geometry& geometry, Range const& range,
104✔
74
                             signed_size_type = -1, signed_size_type = 0)
75
    {
76
        using point_type = typename boost::range_value<Range>::type;
77

78
        auto const end = boost::end(range);
104✔
79
        for (auto it = boost::begin(range); it != end; ++it)
340✔
80
        {
81
            to_range_point::apply<Geometry, point_type>(geometry, *it);
236✔
82
        }
83
    }
104✔
84
};
85

86

87
struct to_polygon_point
88
{
89
    template <typename Polygon, typename Point>
90
    static inline void apply(Polygon& polygon, Point const& point,
754✔
91
                             signed_size_type ring_index, signed_size_type = 0)
92
    {
93
        using ring_type = typename ring_type<Polygon>::type;
94

95
        if (ring_index == -1)
754✔
96
        {
97
            auto&& ext_ring = exterior_ring(polygon);
754✔
98
            to_range_point::apply<ring_type, Point>(ext_ring, point);
754✔
99
        }
100
        else if (ring_index < signed_size_type(num_interior_rings(polygon)))
×
101
        {
102
            auto&& int_rings = interior_rings(polygon);
×
103
            to_range_point::apply<ring_type, Point>(range::at(int_rings, ring_index), point);
×
104
        }
105
    }
754✔
106
};
107

108

109
struct to_polygon_range
110
{
111
    template <typename Polygon, typename Range>
112
    static inline void apply(Polygon& polygon, Range const& range,
16✔
113
                             signed_size_type ring_index, signed_size_type = 0)
114
    {
115
        using ring_type = typename ring_type<Polygon>::type;
116
        using exterior_ring_type = typename ring_return_type<Polygon>::type;
117
        using interior_ring_range_type = typename interior_return_type<Polygon>::type;
118

119
        if (ring_index == -1)
16✔
120
        {
121
            exterior_ring_type ext_ring = exterior_ring(polygon);
16✔
122
            to_range_range::apply<ring_type, Range>(ext_ring, range);
16✔
123
        }
124
        else if (ring_index < signed_size_type(num_interior_rings(polygon)))
×
125
        {
126
            interior_ring_range_type int_rings = interior_rings(polygon);
×
127
            to_range_range::apply<ring_type, Range>(range::at(int_rings, ring_index), range);
×
128
        }
129
    }
16✔
130
};
131

132

133
template <typename Policy>
134
struct to_multigeometry
135
{
136
    template <typename MultiGeometry, typename RangeOrPoint>
137
    static inline void apply(MultiGeometry& multigeometry,
32✔
138
                             RangeOrPoint const& range_or_point,
139
                             signed_size_type ring_index, signed_size_type multi_index)
140
    {
141
        Policy::template apply
142
            <
143
                typename boost::range_value<MultiGeometry>::type,
144
                RangeOrPoint
145
            >(range::at(multigeometry, multi_index), range_or_point, ring_index);
32✔
146
    }
32✔
147
};
148

149

150
}} // namespace detail::append
151
#endif // DOXYGEN_NO_DETAIL
152

153

154
#ifndef DOXYGEN_NO_DISPATCH
155
namespace dispatch
156
{
157

158
template
159
<
160
    typename Geometry,
161
    typename RangeOrPoint,
162
    typename Tag = typename geometry::tag<Geometry>::type,
163
    typename OtherTag = typename geometry::tag<RangeOrPoint>::type
164
>
165
struct append
166
    : detail::append::append_no_action
167
{};
168

169
template <typename Geometry, typename Point>
170
struct append<Geometry, Point, linestring_tag, point_tag>
171
    : detail::append::to_range_point
172
{};
173

174
template <typename Geometry, typename Point>
175
struct append<Geometry, Point, ring_tag, point_tag>
176
    : detail::append::to_range_point
177
{};
178

179
template <typename Polygon, typename Point>
180
struct append<Polygon, Point, polygon_tag, point_tag>
181
        : detail::append::to_polygon_point
182
{};
183

184
template <typename Geometry, typename Range, typename RangeTag>
185
struct append<Geometry, Range, linestring_tag, RangeTag>
186
    : detail::append::to_range_range
187
{};
188

189
template <typename Geometry, typename Range, typename RangeTag>
190
struct append<Geometry, Range, ring_tag, RangeTag>
191
    : detail::append::to_range_range
192
{};
193

194
template <typename Polygon, typename Range, typename RangeTag>
195
struct append<Polygon, Range, polygon_tag, RangeTag>
196
        : detail::append::to_polygon_range
197
{};
198

199

200
template <typename Geometry, typename Point>
201
struct append<Geometry, Point, multi_point_tag, point_tag>
202
    : detail::append::to_range_point
203
{};
204

205
template <typename Geometry, typename Range, typename RangeTag>
206
struct append<Geometry, Range, multi_point_tag, RangeTag>
207
    : detail::append::to_range_range
208
{};
209

210
template <typename MultiGeometry, typename Point>
211
struct append<MultiGeometry, Point, multi_linestring_tag, point_tag>
212
    : detail::append::to_multigeometry<detail::append::to_range_point>
213
{};
214

215
template <typename MultiGeometry, typename Range, typename RangeTag>
216
struct append<MultiGeometry, Range, multi_linestring_tag, RangeTag>
217
    : detail::append::to_multigeometry<detail::append::to_range_range>
218
{};
219

220
template <typename MultiGeometry, typename Point>
221
struct append<MultiGeometry, Point, multi_polygon_tag, point_tag>
222
    : detail::append::to_multigeometry<detail::append::to_polygon_point>
223
{};
224

225
template <typename MultiGeometry, typename Range, typename RangeTag>
226
struct append<MultiGeometry, Range, multi_polygon_tag, RangeTag>
227
    : detail::append::to_multigeometry<detail::append::to_polygon_range>
228
{};
229

230

231
template <typename Geometry, typename RangeOrPoint, typename OtherTag>
232
struct append<Geometry, RangeOrPoint, dynamic_geometry_tag, OtherTag>
233
{
234
    static inline void apply(Geometry& geometry,
97✔
235
                             RangeOrPoint const& range_or_point,
236
                             signed_size_type ring_index, signed_size_type multi_index)
237
    {
238
        traits::visit<Geometry>::apply([&](auto & g)
291✔
239
        {
240
            append
241
                <
242
                    std::remove_reference_t<decltype(g)>, RangeOrPoint
243
                >::apply(g, range_or_point, ring_index, multi_index);
97✔
244
        }, geometry);
245
    }
97✔
246
};
247

248
// TODO: It's unclear how append should work for GeometryCollection because
249
//   it can hold multiple different geometries.
250

251
} // namespace dispatch
252
#endif // DOXYGEN_NO_DISPATCH
253

254

255
/*!
256
\brief Appends one or more points to a linestring, ring, polygon, multi-geometry
257
\ingroup append
258
\tparam Geometry \tparam_geometry
259
\tparam RangeOrPoint Either a range or a point, fullfilling Boost.Range concept or Boost.Geometry Point Concept
260
\param geometry \param_geometry
261
\param range_or_point The point or range to add
262
\param ring_index The index of the ring in case of a polygon:
263
    exterior ring (-1, the default) or  interior ring index
264
\param multi_index The index of the geometry to which the points are appended
265

266
\qbk{[include reference/algorithms/append.qbk]}
267
}
268
 */
269
template <typename Geometry, typename RangeOrPoint>
270
inline void append(Geometry& geometry, RangeOrPoint const& range_or_point,
265,024✔
271
                   signed_size_type ring_index = -1, signed_size_type multi_index = 0)
272
{
273
    concepts::check<Geometry>();
265,024✔
274

275
    dispatch::append
276
        <
277
            Geometry, RangeOrPoint
278
        >::apply(geometry, range_or_point, ring_index, multi_index);
265,024✔
279
}
265,024✔
280

281

282
}} // namespace boost::geometry
283

284

285
#endif // BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc