1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. 4 5 // This file was modified by Oracle on 2013, 2014, 2015, 2017. 6 // Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. 7 8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 9 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) 13 14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP 15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP 16 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> 20 21 #include <boost/geometry/algorithms/detail/relate/result.hpp> 22 #include <boost/geometry/algorithms/detail/relate/topology_check.hpp> 23 24 #include <boost/geometry/util/condition.hpp> 25 26 namespace boost { namespace geometry 27 { 28 29 #ifndef DOXYGEN_NO_DETAIL 30 namespace detail { namespace relate { 31 32 // non-point geometry 33 template <typename Point, typename Geometry, bool Transpose = false> 34 struct point_geometry 35 { 36 // TODO: interrupt only if the topology check is complex 37 38 static const bool interruption_enabled = true; 39 40 template <typename Result, typename Strategy> applyboost::geometry::detail::relate::point_geometry41 static inline void apply(Point const& point, Geometry const& geometry, Result & result, Strategy const& strategy) 42 { 43 int pig = detail::within::point_in_geometry(point, geometry, strategy); 44 45 if ( pig > 0 ) // within 46 { 47 relate::set<interior, interior, '0', Transpose>(result); 48 } 49 else if ( pig == 0 ) 50 { 51 relate::set<interior, boundary, '0', Transpose>(result); 52 } 53 else // pig < 0 - not within 54 { 55 relate::set<interior, exterior, '0', Transpose>(result); 56 } 57 58 relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result); 59 60 if ( BOOST_GEOMETRY_CONDITION(result.interrupt) ) 61 return; 62 63 typedef detail::relate::topology_check<Geometry> tc_t; 64 if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result) 65 || relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) ) 66 { 67 // the point is on the boundary 68 if ( pig == 0 ) 69 { 70 // NOTE: even for MLs, if there is at least one boundary point, 71 // somewhere there must be another one 72 relate::set<exterior, interior, tc_t::interior, Transpose>(result); 73 relate::set<exterior, boundary, tc_t::boundary, Transpose>(result); 74 } 75 else 76 { 77 // check if there is a boundary in Geometry 78 tc_t tc(geometry); 79 if ( tc.has_interior() ) 80 relate::set<exterior, interior, tc_t::interior, Transpose>(result); 81 if ( tc.has_boundary() ) 82 relate::set<exterior, boundary, tc_t::boundary, Transpose>(result); 83 } 84 } 85 } 86 }; 87 88 // transposed result of point_geometry 89 template <typename Geometry, typename Point> 90 struct geometry_point 91 { 92 // TODO: interrupt only if the topology check is complex 93 94 static const bool interruption_enabled = true; 95 96 template <typename Result, typename Strategy> applyboost::geometry::detail::relate::geometry_point97 static inline void apply(Geometry const& geometry, Point const& point, Result & result, Strategy const& strategy) 98 { 99 point_geometry<Point, Geometry, true>::apply(point, geometry, result, strategy); 100 } 101 }; 102 103 // TODO: rewrite the folowing: 104 105 //// NOTE: Those tests should be consistent with within(Point, Box) and covered_by(Point, Box) 106 //// There is no EPS used in those functions, values are compared using < or <= 107 //// so comparing MIN and MAX in the same way should be fine 108 // 109 //template <typename Box, std::size_t I = 0, std::size_t D = geometry::dimension<Box>::value> 110 //struct box_has_interior 111 //{ 112 // static inline bool apply(Box const& box) 113 // { 114 // return geometry::get<min_corner, I>(box) < geometry::get<max_corner, I>(box) 115 // && box_has_interior<Box, I + 1, D>::apply(box); 116 // } 117 //}; 118 // 119 //template <typename Box, std::size_t D> 120 //struct box_has_interior<Box, D, D> 121 //{ 122 // static inline bool apply(Box const&) { return true; } 123 //}; 124 // 125 //// NOTE: especially important here (see the NOTE above). 126 // 127 //template <typename Box, std::size_t I = 0, std::size_t D = geometry::dimension<Box>::value> 128 //struct box_has_equal_min_max 129 //{ 130 // static inline bool apply(Box const& box) 131 // { 132 // return geometry::get<min_corner, I>(box) == geometry::get<max_corner, I>(box) 133 // && box_has_equal_min_max<Box, I + 1, D>::apply(box); 134 // } 135 //}; 136 // 137 //template <typename Box, std::size_t D> 138 //struct box_has_equal_min_max<Box, D, D> 139 //{ 140 // static inline bool apply(Box const&) { return true; } 141 //}; 142 // 143 //template <typename Point, typename Box> 144 //struct point_box 145 //{ 146 // static inline result apply(Point const& point, Box const& box) 147 // { 148 // result res; 149 // 150 // if ( geometry::within(point, box) ) // this also means that the box has interior 151 // { 152 // return result("0FFFFFTTT"); 153 // } 154 // else if ( geometry::covered_by(point, box) ) // point is on the boundary 155 // { 156 // //if ( box_has_interior<Box>::apply(box) ) 157 // //{ 158 // // return result("F0FFFFTTT"); 159 // //} 160 // //else if ( box_has_equal_min_max<Box>::apply(box) ) // no boundary outside point 161 // //{ 162 // // return result("F0FFFFFFT"); 163 // //} 164 // //else // no interior outside point 165 // //{ 166 // // return result("F0FFFFFTT"); 167 // //} 168 // return result("F0FFFF**T"); 169 // } 170 // else 171 // { 172 // /*if ( box_has_interior<Box>::apply(box) ) 173 // { 174 // return result("FF0FFFTTT"); 175 // } 176 // else 177 // { 178 // return result("FF0FFFFTT"); 179 // }*/ 180 // return result("FF0FFF*TT"); 181 // } 182 // 183 // return res; 184 // } 185 //}; 186 // 187 //template <typename Box, typename Point> 188 //struct box_point 189 //{ 190 // static inline result apply(Box const& box, Point const& point) 191 // { 192 // if ( geometry::within(point, box) ) 193 // return result("0FTFFTFFT"); 194 // else if ( geometry::covered_by(point, box) ) 195 // return result("FF*0F*FFT"); 196 // else 197 // return result("FF*FFT0FT"); 198 // } 199 //}; 200 201 }} // namespace detail::relate 202 #endif // DOXYGEN_NO_DETAIL 203 204 }} // namespace boost::geometry 205 206 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_GEOMETRY_HPP 207