]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/point_on_border.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / point_on_border.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
7 // This file was modified by Oracle on 2017, 2018.
8 // Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
13
14 // Use, modification and distribution is subject to the Boost Software License,
15 // Version 1.Dimension. (See accompanying file LICENSE_1_0.txt or copy at
16 // http://www.boost.org/LICENSE_1_0.txt)
17
18 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
19 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
20
21
22 #include <cstddef>
23
24 #include <boost/range.hpp>
25 #include <boost/static_assert.hpp>
26
27 #include <boost/geometry/core/tags.hpp>
28 #include <boost/geometry/core/point_type.hpp>
29 #include <boost/geometry/core/ring_type.hpp>
30
31 #include <boost/geometry/geometries/concepts/check.hpp>
32
33 #include <boost/geometry/algorithms/assign.hpp>
34 #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
35 #include <boost/geometry/algorithms/detail/equals/point_point.hpp>
36
37 #include <boost/geometry/util/condition.hpp>
38
39
40 namespace boost { namespace geometry
41 {
42
43
44 #ifndef DOXYGEN_NO_DETAIL
45 namespace detail { namespace point_on_border
46 {
47
48
49 struct get_point
50 {
51 template <typename Point>
52 static inline bool apply(Point& destination, Point const& source)
53 {
54 destination = source;
55 return true;
56 }
57 };
58
59
60 struct point_on_range
61 {
62 // Version with iterator
63 template<typename Point, typename Iterator>
64 static inline bool apply(Point& point, Iterator begin, Iterator end)
65 {
66 if (begin == end)
67 {
68 return false;
69 }
70
71 geometry::detail::conversion::convert_point_to_point(*begin, point);
72 return true;
73 }
74
75 // Version with range
76 template<typename Point, typename Range>
77 static inline bool apply(Point& point, Range const& range)
78 {
79 return apply(point, boost::begin(range), boost::end(range));
80 }
81 };
82
83
84 struct point_on_polygon
85 {
86 template<typename Point, typename Polygon>
87 static inline bool apply(Point& point, Polygon const& polygon)
88 {
89 return point_on_range::apply(point, exterior_ring(polygon));
90 }
91 };
92
93
94 struct point_on_box
95 {
96 template<typename Point, typename Box>
97 static inline bool apply(Point& point, Box const& box)
98 {
99 detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
100 return true;
101 }
102 };
103
104
105 template <typename Policy>
106 struct point_on_multi
107 {
108 template<typename Point, typename MultiGeometry>
109 static inline bool apply(Point& point, MultiGeometry const& multi)
110 {
111 // Take a point on the first multi-geometry
112 // (i.e. the first that is not empty)
113 for (typename boost::range_iterator
114 <
115 MultiGeometry const
116 >::type it = boost::begin(multi);
117 it != boost::end(multi);
118 ++it)
119 {
120 if (Policy::apply(point, *it))
121 {
122 return true;
123 }
124 }
125 return false;
126 }
127 };
128
129
130 }} // namespace detail::point_on_border
131 #endif // DOXYGEN_NO_DETAIL
132
133
134 #ifndef DOXYGEN_NO_DISPATCH
135 namespace dispatch
136 {
137
138
139 template <typename GeometryTag>
140 struct point_on_border
141 {};
142
143 template <>
144 struct point_on_border<point_tag>
145 : detail::point_on_border::get_point
146 {};
147
148 template <>
149 struct point_on_border<linestring_tag>
150 : detail::point_on_border::point_on_range
151 {};
152
153 template <>
154 struct point_on_border<ring_tag>
155 : detail::point_on_border::point_on_range
156 {};
157
158 template <>
159 struct point_on_border<polygon_tag>
160 : detail::point_on_border::point_on_polygon
161 {};
162
163 template <>
164 struct point_on_border<box_tag>
165 : detail::point_on_border::point_on_box
166 {};
167
168
169 template <>
170 struct point_on_border<multi_polygon_tag>
171 : detail::point_on_border::point_on_multi
172 <
173 detail::point_on_border::point_on_polygon
174 >
175 {};
176
177
178 template <>
179 struct point_on_border<multi_linestring_tag>
180 : detail::point_on_border::point_on_multi
181 <
182 detail::point_on_border::point_on_range
183 >
184 {};
185
186
187 } // namespace dispatch
188 #endif // DOXYGEN_NO_DISPATCH
189
190
191 /*!
192 \brief Take point on a border
193 \ingroup overlay
194 \tparam Geometry geometry type. This also defines the type of the output point
195 \param point to assign
196 \param geometry geometry to take point from
197 \return TRUE if successful, else false.
198 It is only false if polygon/line have no points
199 \note for a polygon, it is always a point on the exterior ring
200 */
201 template <typename Point, typename Geometry>
202 inline bool point_on_border(Point& point, Geometry const& geometry)
203 {
204 concepts::check<Point>();
205 concepts::check<Geometry const>();
206
207 return dispatch::point_on_border
208 <
209 typename tag<Geometry>::type
210 >::apply(point, geometry);
211 }
212
213
214 }} // namespace boost::geometry
215
216
217 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP