• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
applyboost::geometry::detail::point_on_border::get_point52     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>
applyboost::geometry::detail::point_on_border::point_on_range64     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>
applyboost::geometry::detail::point_on_border::point_on_range77     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>
applyboost::geometry::detail::point_on_border::point_on_polygon87     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>
applyboost::geometry::detail::point_on_border::point_on_box97     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>
applyboost::geometry::detail::point_on_border::point_on_multi109     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>
point_on_border(Point & point,Geometry const & 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
218