1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
8 // This file was modified by Oracle on 2013-2017.
9 // Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
21 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP
22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP
26 #include <boost/range.hpp>
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/tag_cast.hpp>
35 #include <boost/geometry/core/tags.hpp>
37 #include <boost/geometry/algorithms/covered_by.hpp>
38 #include <boost/geometry/algorithms/not_implemented.hpp>
40 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
41 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
42 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
44 #include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
45 #include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
46 #include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
47 #include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
49 #include <boost/geometry/algorithms/dispatch/disjoint.hpp>
52 namespace boost { namespace geometry
55 #ifndef DOXYGEN_NO_DETAIL
56 namespace detail { namespace disjoint
59 template <typename Geometry1, typename Geometry2,
60 typename Tag1 = typename tag<Geometry1>::type,
61 typename Tag1OrMulti = typename tag_cast<Tag1, multi_tag>::type>
62 struct disjoint_no_intersections_policy
65 \tparam Strategy point_in_geometry strategy
67 template <typename Strategy>
68 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
70 typedef typename point_type<Geometry1>::type point1_type;
72 geometry::point_on_border(p, g1);
74 return !geometry::covered_by(p, g2, strategy);
78 template <typename Geometry1, typename Geometry2, typename Tag1>
79 struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
82 \tparam Strategy point_in_geometry strategy
84 template <typename Strategy>
85 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
87 // TODO: use partition or rtree on g2
88 typedef typename boost::range_iterator<Geometry1 const>::type iterator;
89 for ( iterator it = boost::begin(g1) ; it != boost::end(g1) ; ++it )
91 typedef typename boost::range_value<Geometry1 const>::type value_type;
92 if ( ! disjoint_no_intersections_policy<value_type const, Geometry2>
93 ::apply(*it, g2, strategy) )
103 template<typename Geometry1, typename Geometry2,
104 typename NoIntersectionsPolicy
105 = disjoint_no_intersections_policy<Geometry1, Geometry2> >
106 struct disjoint_linear_areal
109 \tparam Strategy relate (segments intersection) strategy
111 template <typename Strategy>
112 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
114 // if there are intersections - return false
115 if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2, strategy) )
120 return NoIntersectionsPolicy
122 strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>());
133 typename Tag = typename tag<Areal>::type
135 struct disjoint_segment_areal
136 : not_implemented<Segment, Areal>
140 template <typename Segment, typename Polygon>
141 class disjoint_segment_areal<Segment, Polygon, polygon_tag>
144 template <typename InteriorRings, typename Strategy>
146 bool check_interior_rings(InteriorRings const& interior_rings,
147 Segment const& segment,
148 Strategy const& strategy)
150 typedef typename boost::range_value<InteriorRings>::type ring_type;
152 typedef unary_disjoint_geometry_to_query_geometry
156 disjoint_range_segment_or_box
158 ring_type, closure<ring_type>::value, Segment
160 > unary_predicate_type;
162 return check_iterator_range
165 >::apply(boost::begin(interior_rings),
166 boost::end(interior_rings),
167 unary_predicate_type(segment, strategy));
172 template <typename IntersectionStrategy>
173 static inline bool apply(Segment const& segment,
174 Polygon const& polygon,
175 IntersectionStrategy const& strategy)
177 typedef typename geometry::ring_type<Polygon>::type ring;
179 if ( !disjoint_range_segment_or_box
181 ring, closure<Polygon>::value, Segment
182 >::apply(geometry::exterior_ring(polygon), segment, strategy) )
187 if ( !check_interior_rings(geometry::interior_rings(polygon), segment, strategy) )
192 typename point_type<Segment>::type p;
193 detail::assign_point_from_index<0>(segment, p);
195 return !geometry::covered_by(p, polygon,
196 strategy.template get_point_in_geometry_strategy<Segment, Polygon>());
201 template <typename Segment, typename MultiPolygon>
202 struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
204 template <typename IntersectionStrategy>
205 static inline bool apply(Segment const& segment, MultiPolygon const& multipolygon,
206 IntersectionStrategy const& strategy)
208 return multirange_constant_size_geometry
210 MultiPolygon, Segment
211 >::apply(multipolygon, segment, strategy);
216 template <typename Segment, typename Ring>
217 struct disjoint_segment_areal<Segment, Ring, ring_tag>
219 template <typename IntersectionStrategy>
220 static inline bool apply(Segment const& segment,
222 IntersectionStrategy const& strategy)
224 if ( !disjoint_range_segment_or_box
226 Ring, closure<Ring>::value, Segment
227 >::apply(ring, segment, strategy) )
232 typename point_type<Segment>::type p;
233 detail::assign_point_from_index<0>(segment, p);
235 return !geometry::covered_by(p, ring,
236 strategy.template get_point_in_geometry_strategy<Segment, Ring>());
241 }} // namespace detail::disjoint
242 #endif // DOXYGEN_NO_DETAIL
247 #ifndef DOXYGEN_NO_DISPATCH
252 template <typename Linear, typename Areal>
253 struct disjoint<Linear, Areal, 2, linear_tag, areal_tag, false>
254 : public detail::disjoint::disjoint_linear_areal<Linear, Areal>
258 template <typename Areal, typename Linear>
259 struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
261 template <typename Strategy>
262 static inline bool apply(Areal const& areal, Linear const& linear,
263 Strategy const& strategy)
265 return detail::disjoint::disjoint_linear_areal
268 >::apply(linear, areal, strategy);
273 template <typename Areal, typename Segment>
274 struct disjoint<Areal, Segment, 2, areal_tag, segment_tag, false>
276 template <typename Strategy>
277 static inline bool apply(Areal const& g1, Segment const& g2,
278 Strategy const& strategy)
280 return detail::disjoint::disjoint_segment_areal
283 >::apply(g2, g1, strategy);
288 template <typename Segment, typename Areal>
289 struct disjoint<Segment, Areal, 2, segment_tag, areal_tag, false>
290 : detail::disjoint::disjoint_segment_areal<Segment, Areal>
294 } // namespace dispatch
295 #endif // DOXYGEN_NO_DISPATCH
298 }} // namespace boost::geometry
301 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP