1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. 6 // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. 7 8 // This file was modified by Oracle on 2013-2019. 9 // Modifications copyright (c) 2013-2019, Oracle and/or its affiliates. 10 11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 13 14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library 15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. 16 17 // Use, modification and distribution is subject to the Boost Software License, 18 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 19 // http://www.boost.org/LICENSE_1_0.txt) 20 21 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_SEGMENT_OR_BOX_HPP 22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_SEGMENT_OR_BOX_HPP 23 24 25 #include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp> 26 #include <boost/geometry/algorithms/dispatch/disjoint.hpp> 27 #include <boost/geometry/algorithms/not_implemented.hpp> 28 #include <boost/geometry/core/closure.hpp> 29 #include <boost/geometry/geometries/segment.hpp> 30 #include <boost/geometry/util/range.hpp> 31 #include <boost/geometry/views/closeable_view.hpp> 32 33 34 namespace boost { namespace geometry 35 { 36 37 38 #ifndef DOXYGEN_NO_DETAIL 39 namespace detail { namespace disjoint 40 { 41 42 43 template 44 < 45 typename SegmentOrBox, 46 typename Tag = typename tag<SegmentOrBox>::type 47 > 48 struct disjoint_point_segment_or_box 49 : not_implemented<Tag> 50 {}; 51 52 template <typename Segment> 53 struct disjoint_point_segment_or_box<Segment, segment_tag> 54 { 55 template <typename Point, typename Strategy> applyboost::geometry::detail::disjoint::disjoint_point_segment_or_box56 static inline bool apply(Point const& point, Segment const& segment, Strategy const& strategy) 57 { 58 return dispatch::disjoint 59 < 60 Point, Segment 61 >::apply(point, segment, 62 strategy.template get_point_in_geometry_strategy<Point, Segment>()); 63 } 64 }; 65 66 template <typename Box> 67 struct disjoint_point_segment_or_box<Box, box_tag> 68 { 69 template <typename Point, typename Strategy> applyboost::geometry::detail::disjoint::disjoint_point_segment_or_box70 static inline bool apply(Point const& point, Box const& box, Strategy const& strategy) 71 { 72 return dispatch::disjoint 73 < 74 Point, Box 75 >::apply(point, box, 76 strategy.get_disjoint_point_box_strategy()); 77 } 78 }; 79 80 81 template 82 < 83 typename Range, 84 closure_selector Closure, 85 typename SegmentOrBox 86 > 87 struct disjoint_range_segment_or_box 88 { 89 template <typename Strategy> applyboost::geometry::detail::disjoint::disjoint_range_segment_or_box90 static inline bool apply(Range const& range, 91 SegmentOrBox const& segment_or_box, 92 Strategy const& strategy) 93 { 94 typedef typename closeable_view<Range const, Closure>::type view_type; 95 96 typedef typename ::boost::range_value<view_type>::type point_type; 97 typedef typename ::boost::range_iterator 98 < 99 view_type const 100 >::type const_iterator; 101 102 typedef typename ::boost::range_size<view_type>::type size_type; 103 104 typedef typename geometry::model::referring_segment 105 < 106 point_type const 107 > range_segment; 108 109 view_type view(range); 110 111 const size_type count = ::boost::size(view); 112 113 if ( count == 0 ) 114 { 115 return false; 116 } 117 else if ( count == 1 ) 118 { 119 return disjoint_point_segment_or_box 120 < 121 SegmentOrBox 122 >::apply(geometry::range::front<view_type const>(view), 123 segment_or_box, 124 strategy); 125 } 126 else 127 { 128 const_iterator it0 = ::boost::begin(view); 129 const_iterator it1 = ::boost::begin(view) + 1; 130 const_iterator last = ::boost::end(view); 131 132 for ( ; it1 != last ; ++it0, ++it1 ) 133 { 134 range_segment rng_segment(*it0, *it1); 135 if ( !dispatch::disjoint 136 < 137 range_segment, SegmentOrBox 138 >::apply(rng_segment, segment_or_box, strategy) ) 139 { 140 return false; 141 } 142 } 143 return true; 144 } 145 } 146 }; 147 148 149 150 151 template 152 < 153 typename Linear, 154 typename SegmentOrBox, 155 typename Tag = typename tag<Linear>::type 156 > 157 struct disjoint_linear_segment_or_box 158 : not_implemented<Linear, SegmentOrBox> 159 {}; 160 161 162 template <typename Linestring, typename SegmentOrBox> 163 struct disjoint_linear_segment_or_box<Linestring, SegmentOrBox, linestring_tag> 164 : disjoint_range_segment_or_box<Linestring, closed, SegmentOrBox> 165 {}; 166 167 168 template <typename MultiLinestring, typename SegmentOrBox> 169 struct disjoint_linear_segment_or_box 170 < 171 MultiLinestring, SegmentOrBox, multi_linestring_tag 172 > : multirange_constant_size_geometry<MultiLinestring, SegmentOrBox> 173 {}; 174 175 176 }} // namespace detail::disjoint 177 #endif // DOXYGEN_NO_DETAIL 178 179 180 #ifndef DOXYGEN_NO_DISPATCH 181 namespace dispatch 182 { 183 184 185 template <typename Linear, typename Segment> 186 struct disjoint<Linear, Segment, 2, linear_tag, segment_tag, false> 187 : detail::disjoint::disjoint_linear_segment_or_box<Linear, Segment> 188 {}; 189 190 191 template <typename Linear, typename Box, std::size_t DimensionCount> 192 struct disjoint<Linear, Box, DimensionCount, linear_tag, box_tag, false> 193 : detail::disjoint::disjoint_linear_segment_or_box<Linear, Box> 194 {}; 195 196 197 } // namespace dispatch 198 #endif // DOXYGEN_NO_DISPATCH 199 200 201 }} // namespace boost::geometry 202 203 204 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_SEGMENT_OR_BOX_HPP 205