• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_AREAL_AREAL_HPP
22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_AREAL_AREAL_HPP
23 
24 #include <boost/geometry/core/point_type.hpp>
25 
26 #include <boost/geometry/algorithms/covered_by.hpp>
27 #include <boost/geometry/algorithms/detail/for_each_range.hpp>
28 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
29 
30 #include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
31 #include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
32 
33 #include <boost/geometry/iterators/segment_iterator.hpp>
34 
35 
36 namespace boost { namespace geometry
37 {
38 
39 
40 #ifndef DOXYGEN_NO_DETAIL
41 namespace detail { namespace disjoint
42 {
43 
44 template <typename Geometry1, typename Geometry2, typename Strategy>
point_on_border_covered_by(Geometry1 const & geometry1,Geometry2 const & geometry2,Strategy const & strategy)45 inline bool point_on_border_covered_by(Geometry1 const& geometry1,
46                                        Geometry2 const& geometry2,
47                                        Strategy const& strategy)
48 {
49     typename geometry::point_type<Geometry1>::type pt;
50     return geometry::point_on_border(pt, geometry1)
51         && geometry::covered_by(pt, geometry2, strategy);
52 }
53 
54 /*!
55 \tparam Strategy point_in_geometry strategy
56 */
57 template<typename Geometry, typename Strategy>
58 struct check_each_ring_for_within
59 {
60     bool not_disjoint;
61     Geometry const& m_geometry;
62     Strategy const& m_strategy;
63 
check_each_ring_for_withinboost::geometry::detail::disjoint::check_each_ring_for_within64     inline check_each_ring_for_within(Geometry const& g,
65                                       Strategy const& strategy)
66         : not_disjoint(false)
67         , m_geometry(g)
68         , m_strategy(strategy)
69     {}
70 
71     template <typename Range>
applyboost::geometry::detail::disjoint::check_each_ring_for_within72     inline void apply(Range const& range)
73     {
74         not_disjoint = not_disjoint
75                     || point_on_border_covered_by(range, m_geometry, m_strategy);
76     }
77 };
78 
79 
80 /*!
81 \tparam Strategy point_in_geometry strategy
82 */
83 template <typename FirstGeometry, typename SecondGeometry, typename Strategy>
rings_containing(FirstGeometry const & geometry1,SecondGeometry const & geometry2,Strategy const & strategy)84 inline bool rings_containing(FirstGeometry const& geometry1,
85                              SecondGeometry const& geometry2,
86                              Strategy const& strategy)
87 {
88     check_each_ring_for_within
89         <
90             FirstGeometry, Strategy
91         > checker(geometry1, strategy);
92     geometry::detail::for_each_range(geometry2, checker);
93     return checker.not_disjoint;
94 }
95 
96 
97 
98 template <typename Geometry1, typename Geometry2>
99 struct areal_areal
100 {
101     /*!
102     \tparam Strategy relate (segments intersection) strategy
103     */
104     template <typename Strategy>
applyboost::geometry::detail::disjoint::areal_areal105     static inline bool apply(Geometry1 const& geometry1,
106                              Geometry2 const& geometry2,
107                              Strategy const& strategy)
108     {
109         if ( ! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy) )
110         {
111             return false;
112         }
113 
114         // If there is no intersection of segments, they might located
115         // inside each other
116 
117         // We check that using a point on the border (external boundary),
118         // and see if that is contained in the other geometry. And vice versa.
119 
120         if ( rings_containing(geometry1, geometry2,
121                               strategy.template get_point_in_geometry_strategy<Geometry2, Geometry1>())
122           || rings_containing(geometry2, geometry1,
123                               strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>()) )
124         {
125             return false;
126         }
127 
128         return true;
129     }
130 };
131 
132 
133 template <typename Areal, typename Box>
134 struct areal_box
135 {
136     /*!
137     \tparam Strategy relate (segments intersection) strategy
138     */
139     template <typename Strategy>
applyboost::geometry::detail::disjoint::areal_box140     static inline bool apply(Areal const& areal,
141                              Box const& box,
142                              Strategy const& strategy)
143     {
144         if ( ! for_each_segment(geometry::segments_begin(areal),
145                                 geometry::segments_end(areal),
146                                 box,
147                                 strategy.get_disjoint_segment_box_strategy()) )
148         {
149             return false;
150         }
151 
152         // If there is no intersection of any segment and box,
153         // the box might be located inside areal geometry
154 
155         if ( point_on_border_covered_by(box, areal,
156                 strategy.template get_point_in_geometry_strategy<Box, Areal>()) )
157         {
158             return false;
159         }
160 
161         return true;
162     }
163 
164 private:
165     template <typename SegIter, typename Strategy>
for_each_segmentboost::geometry::detail::disjoint::areal_box166     static inline bool for_each_segment(SegIter first,
167                                         SegIter last,
168                                         Box const& box,
169                                         Strategy const& strategy)
170     {
171         for ( ; first != last ; ++first)
172         {
173             if (! disjoint_segment_box::apply(*first, box, strategy))
174             {
175                 return false;
176             }
177         }
178         return true;
179     }
180 };
181 
182 
183 }} // namespace detail::disjoint
184 #endif // DOXYGEN_NO_DETAIL
185 
186 
187 
188 
189 #ifndef DOXYGEN_NO_DISPATCH
190 namespace dispatch
191 {
192 
193 
194 template <typename Areal1, typename Areal2>
195 struct disjoint<Areal1, Areal2, 2, areal_tag, areal_tag, false>
196     : detail::disjoint::areal_areal<Areal1, Areal2>
197 {};
198 
199 
200 template <typename Areal, typename Box>
201 struct disjoint<Areal, Box, 2, areal_tag, box_tag, false>
202     : detail::disjoint::areal_box<Areal, Box>
203 {};
204 
205 
206 } // namespace dispatch
207 #endif // DOXYGEN_NO_DISPATCH
208 
209 
210 }} // namespace boost::geometry
211 
212 
213 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_AREAL_AREAL_HPP
214