3 // Copyright (c) 2017-2020 Oracle and/or its affiliates.
4 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP
12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP
15 #include <boost/geometry/algorithms/covered_by.hpp>
16 #include <boost/geometry/core/access.hpp>
17 #include <boost/geometry/core/tags.hpp>
18 #include <boost/geometry/iterators/point_iterator.hpp>
21 namespace boost { namespace geometry
25 #ifndef DOXYGEN_NO_DETAIL
26 namespace detail { namespace overlay
33 typename Tag = typename geometry::tag<Geometry>::type
37 typedef geometry::point_iterator<Geometry const> iterator_type;
39 explicit points_range(Geometry const& geometry)
40 : m_geometry(geometry)
43 iterator_type begin() const
45 return geometry::points_begin(m_geometry);
48 iterator_type end() const
50 return geometry::points_end(m_geometry);
53 Geometry const& m_geometry;
55 // Specialized because point_iterator doesn't support boxes
56 template <typename Box>
57 struct points_range<Box, box_tag>
59 typedef typename geometry::point_type<Box>::type point_type;
60 typedef const point_type * iterator_type;
62 explicit points_range(Box const& box)
64 detail::assign_box_corners(box,
65 m_corners[0], m_corners[1], m_corners[2], m_corners[3]);
68 iterator_type begin() const
73 iterator_type end() const
78 point_type m_corners[4];
84 typename Tag = typename geometry::tag<Geometry>::type
86 struct point_in_geometry_helper
88 template <typename Point, typename Strategy>
89 static inline int apply(Point const& point, Geometry const& geometry,
90 Strategy const& strategy)
92 return detail::within::point_in_geometry(point, geometry, strategy);
95 // Specialized because point_in_geometry doesn't support Boxes
96 template <typename Box>
97 struct point_in_geometry_helper<Box, box_tag>
99 template <typename Point, typename Strategy>
100 static inline int apply(Point const& point, Box const& box,
101 Strategy const& strategy)
103 return geometry::covered_by(point, box, strategy) ? 1 : -1;
107 // This function returns
108 // when it finds a point of geometry1 inside or outside geometry2
109 template <typename Geometry1, typename Geometry2, typename Strategy>
110 static inline int range_in_geometry(Geometry1 const& geometry1,
111 Geometry2 const& geometry2,
112 Strategy const& strategy,
113 bool skip_first = false)
116 points_range<Geometry1> points(geometry1);
117 typedef typename points_range<Geometry1>::iterator_type iterator_type;
118 iterator_type const end = points.end();
119 iterator_type it = points.begin();
129 for ( ; it != end; ++it)
131 result = point_in_geometry_helper<Geometry2>::apply(*it, geometry2, strategy);
137 // all points contained entirely by the boundary
141 // This function returns if first_point1 is inside or outside geometry2 or
142 // when it finds a point of geometry1 inside or outside geometry2
143 template <typename Point1, typename Geometry1, typename Geometry2, typename Strategy>
144 inline int range_in_geometry(Point1 const& first_point1,
145 Geometry1 const& geometry1,
146 Geometry2 const& geometry2,
147 Strategy const& strategy)
149 // check a point on border of geometry1 first
150 int result = point_in_geometry_helper<Geometry2>::apply(first_point1, geometry2, strategy);
153 // if a point is on boundary of geometry2
154 // check points of geometry1 until point inside/outside is found
155 // NOTE: skip first point because it should be already tested above
156 result = range_in_geometry(geometry1, geometry2, strategy, true);
162 }} // namespace detail::overlay
163 #endif // DOXYGEN_NO_DETAIL
166 }} // namespace boost::geometry
169 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP