1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2013, 2014, 2015.
6 // Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP
17 #include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
18 //#include <boost/geometry/algorithms/within.hpp>
19 //#include <boost/geometry/algorithms/covered_by.hpp>
21 #include <boost/geometry/algorithms/detail/relate/result.hpp>
22 #include <boost/geometry/algorithms/detail/relate/topology_check.hpp>
24 #include <boost/geometry/util/condition.hpp>
26 namespace boost { namespace geometry
29 #ifndef DOXYGEN_NO_DETAIL
30 namespace detail { namespace relate {
33 template <typename Point, typename Geometry, bool Transpose = false>
36 // TODO: interrupt only if the topology check is complex
38 static const bool interruption_enabled = true;
40 template <typename Result>
41 static inline void apply(Point const& point, Geometry const& geometry, Result & result)
43 int pig = detail::within::point_in_geometry(point, geometry);
45 if ( pig > 0 ) // within
47 relate::set<interior, interior, '0', Transpose>(result);
51 relate::set<interior, boundary, '0', Transpose>(result);
53 else // pig < 0 - not within
55 relate::set<interior, exterior, '0', Transpose>(result);
58 relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
60 if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
63 // the point is on the boundary
66 // NOTE: even for MLs, if there is at least one boundary point,
67 // somewhere there must be another one
69 // check if there are other boundaries outside
70 typedef detail::relate::topology_check<Geometry> tc_t;
71 //tc_t tc(geometry, point);
72 //if ( tc.has_interior )
73 relate::set<exterior, interior, tc_t::interior, Transpose>(result);
74 //if ( tc.has_boundary )
75 relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
79 // check if there is a boundary in Geometry
80 typedef detail::relate::topology_check<Geometry> tc_t;
82 if ( tc.has_interior )
83 relate::set<exterior, interior, tc_t::interior, Transpose>(result);
84 if ( tc.has_boundary )
85 relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
90 // transposed result of point_geometry
91 template <typename Geometry, typename Point>
94 // TODO: interrupt only if the topology check is complex
96 static const bool interruption_enabled = true;
98 template <typename Result>
99 static inline void apply(Geometry const& geometry, Point const& point, Result & result)
101 point_geometry<Point, Geometry, true>::apply(point, geometry, result);
105 // TODO: rewrite the folowing:
107 //// NOTE: Those tests should be consistent with within(Point, Box) and covered_by(Point, Box)
108 //// There is no EPS used in those functions, values are compared using < or <=
109 //// so comparing MIN and MAX in the same way should be fine
111 //template <typename Box, std::size_t I = 0, std::size_t D = geometry::dimension<Box>::value>
112 //struct box_has_interior
114 // static inline bool apply(Box const& box)
116 // return geometry::get<min_corner, I>(box) < geometry::get<max_corner, I>(box)
117 // && box_has_interior<Box, I + 1, D>::apply(box);
121 //template <typename Box, std::size_t D>
122 //struct box_has_interior<Box, D, D>
124 // static inline bool apply(Box const&) { return true; }
127 //// NOTE: especially important here (see the NOTE above).
129 //template <typename Box, std::size_t I = 0, std::size_t D = geometry::dimension<Box>::value>
130 //struct box_has_equal_min_max
132 // static inline bool apply(Box const& box)
134 // return geometry::get<min_corner, I>(box) == geometry::get<max_corner, I>(box)
135 // && box_has_equal_min_max<Box, I + 1, D>::apply(box);
139 //template <typename Box, std::size_t D>
140 //struct box_has_equal_min_max<Box, D, D>
142 // static inline bool apply(Box const&) { return true; }
145 //template <typename Point, typename Box>
148 // static inline result apply(Point const& point, Box const& box)
152 // if ( geometry::within(point, box) ) // this also means that the box has interior
154 // return result("0FFFFFTTT");
156 // else if ( geometry::covered_by(point, box) ) // point is on the boundary
158 // //if ( box_has_interior<Box>::apply(box) )
160 // // return result("F0FFFFTTT");
162 // //else if ( box_has_equal_min_max<Box>::apply(box) ) // no boundary outside point
164 // // return result("F0FFFFFFT");
166 // //else // no interior outside point
168 // // return result("F0FFFFFTT");
170 // return result("F0FFFF**T");
174 // /*if ( box_has_interior<Box>::apply(box) )
176 // return result("FF0FFFTTT");
180 // return result("FF0FFFFTT");
182 // return result("FF0FFF*TT");
189 //template <typename Box, typename Point>
192 // static inline result apply(Box const& box, Point const& point)
194 // if ( geometry::within(point, box) )
195 // return result("0FTFFTFFT");
196 // else if ( geometry::covered_by(point, box) )
197 // return result("FF*0F*FFT");
199 // return result("FF*FFT0FT");
203 }} // namespace detail::relate
204 #endif // DOXYGEN_NO_DETAIL
206 }} // namespace boost::geometry
208 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP