Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / geometry / algorithms / detail / disjoint / linear_areal.hpp
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-2014.
9 // Modifications copyright (c) 2013-2014, 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_AREAL_HPP
22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP
23
24 #include <iterator>
25
26 #include <boost/range.hpp>
27
28 #include <boost/geometry/core/closure.hpp>
29 #include <boost/geometry/core/point_type.hpp>
30 #include <boost/geometry/core/ring_type.hpp>
31 #include <boost/geometry/core/exterior_ring.hpp>
32 #include <boost/geometry/core/interior_rings.hpp>
33 #include <boost/geometry/core/tag.hpp>
34 #include <boost/geometry/core/tags.hpp>
35
36 #include <boost/geometry/algorithms/covered_by.hpp>
37 #include <boost/geometry/algorithms/not_implemented.hpp>
38 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
39
40 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
41 #include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
42 #include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
43 #include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
44
45 #include <boost/geometry/algorithms/dispatch/disjoint.hpp>
46
47
48 namespace boost { namespace geometry
49 {
50
51
52 #ifndef DOXYGEN_NO_DETAIL
53 namespace detail { namespace disjoint
54 {
55
56
57 template<typename Geometry1, typename Geometry2>
58 struct disjoint_linear_areal
59 {
60     static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
61     {
62         // if there are intersections - return false
63         if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2) )
64             return false;
65
66         typedef typename point_type<Geometry1>::type point1_type;
67         point1_type p;
68         geometry::point_on_border(p, g1);
69         return !geometry::covered_by(p, g2);
70     }
71 };
72
73
74
75
76 template
77 <
78     typename Segment,
79     typename Areal,
80     typename Tag = typename tag<Areal>::type
81 >
82 struct disjoint_segment_areal
83     : not_implemented<Segment, Areal>
84 {};
85
86
87 template <typename Segment, typename Polygon>
88 class disjoint_segment_areal<Segment, Polygon, polygon_tag>
89 {
90 private:
91     template <typename RingIterator>
92     static inline bool check_interior_rings(RingIterator first,
93                                             RingIterator beyond,
94                                             Segment const& segment)
95     {
96         for (RingIterator it = first; it != beyond; ++it)
97         {
98             if ( !disjoint_range_segment_or_box
99                      <
100                          typename std::iterator_traits
101                              <
102                                  RingIterator
103                              >::value_type,
104                          closure<Polygon>::value,
105                          Segment
106                      >::apply(*it, segment) )
107             {
108                 return false;
109             }
110         }
111         return true;
112     }
113
114
115     template <typename InteriorRings>
116     static inline
117     bool check_interior_rings(InteriorRings const& interior_rings,
118                               Segment const& segment)
119     {
120         return check_interior_rings(boost::begin(interior_rings),
121                                     boost::end(interior_rings),
122                                     segment);
123     }
124
125
126 public:
127     static inline bool apply(Segment const& segment, Polygon const& polygon)
128     {
129         typedef typename geometry::ring_type<Polygon>::type ring;
130
131         if ( !disjoint_range_segment_or_box
132                  <
133                      ring, closure<Polygon>::value, Segment
134                  >::apply(geometry::exterior_ring(polygon), segment) )
135         {
136             return false;
137         }
138
139         if ( !check_interior_rings(geometry::interior_rings(polygon), segment) )
140         {
141             return false;
142         }
143
144         typename point_type<Segment>::type p;
145         detail::assign_point_from_index<0>(segment, p);
146
147         return !geometry::covered_by(p, polygon);
148     }
149 };
150
151
152 template <typename Segment, typename MultiPolygon>
153 struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
154 {
155     static inline
156     bool apply(Segment const& segment, MultiPolygon const& multipolygon)
157     {
158         return disjoint_multirange_segment_or_box
159             <
160                 MultiPolygon, Segment
161             >::apply(multipolygon, segment);
162     }
163 };
164
165
166 template <typename Segment, typename Ring>
167 struct disjoint_segment_areal<Segment, Ring, ring_tag>
168 {
169     static inline bool apply(Segment const& segment, Ring const& ring)
170     {
171         if ( !disjoint_range_segment_or_box
172                  <
173                      Ring, closure<Ring>::value, Segment
174                  >::apply(ring, segment) )
175         {
176             return false;
177         }
178
179         typename point_type<Segment>::type p;
180         detail::assign_point_from_index<0>(segment, p);
181         
182         return !geometry::covered_by(p, ring);        
183     }
184 };
185
186
187 }} // namespace detail::disjoint
188 #endif // DOXYGEN_NO_DETAIL
189
190
191
192
193 #ifndef DOXYGEN_NO_DISPATCH
194 namespace dispatch
195 {
196
197
198 template <typename Linear, typename Areal>
199 struct disjoint<Linear, Areal, 2, linear_tag, areal_tag, false>
200     : public detail::disjoint::disjoint_linear_areal<Linear, Areal>
201 {};
202
203
204 template <typename Areal, typename Linear>
205 struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
206 {    
207     static inline
208     bool apply(Areal const& areal, Linear const& linear)
209     {
210         return detail::disjoint::disjoint_linear_areal
211             <
212                 Linear, Areal
213             >::apply(linear, areal);
214     }
215 };
216
217
218 template <typename Areal, typename Segment>
219 struct disjoint<Areal, Segment, 2, areal_tag, segment_tag, false>
220 {
221     static inline bool apply(Areal const& g1, Segment const& g2)
222     {
223         return detail::disjoint::disjoint_segment_areal
224             <
225                 Segment, Areal
226             >::apply(g2, g1);
227     }
228 };
229
230
231 template <typename Segment, typename Areal>
232 struct disjoint<Segment, Areal, 2, segment_tag, areal_tag, false>
233     : detail::disjoint::disjoint_segment_areal<Segment, Areal>
234 {};
235
236
237 } // namespace dispatch
238 #endif // DOXYGEN_NO_DISPATCH
239
240
241 }} // namespace boost::geometry
242
243
244 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP