1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2014-2015, Oracle and/or its affiliates.
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
10 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
11 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP
16 #include <boost/range.hpp>
18 #include <boost/geometry/core/assert.hpp>
19 #include <boost/geometry/core/tags.hpp>
21 #include <boost/geometry/geometries/box.hpp>
23 #include <boost/geometry/iterators/segment_iterator.hpp>
25 #include <boost/geometry/algorithms/envelope.hpp>
26 #include <boost/geometry/algorithms/expand.hpp>
28 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
29 #include <boost/geometry/algorithms/detail/partition.hpp>
30 #include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
31 #include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
32 #include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
33 #include <boost/geometry/algorithms/detail/relate/less.hpp>
35 #include <boost/geometry/algorithms/dispatch/disjoint.hpp>
38 namespace boost { namespace geometry
42 #ifndef DOXYGEN_NO_DETAIL
43 namespace detail { namespace disjoint
47 template <typename MultiPoint1, typename MultiPoint2>
48 class multipoint_multipoint
51 template <typename Iterator>
52 class unary_disjoint_predicate
53 : detail::relate::less
56 typedef detail::relate::less base_type;
59 unary_disjoint_predicate(Iterator first, Iterator last)
60 : base_type(), m_first(first), m_last(last)
63 template <typename Point>
64 inline bool apply(Point const& point) const
66 return !std::binary_search(m_first,
69 static_cast<base_type const&>(*this));
73 Iterator m_first, m_last;
77 static inline bool apply(MultiPoint1 const& multipoint1,
78 MultiPoint2 const& multipoint2)
80 BOOST_GEOMETRY_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
82 typedef typename boost::range_value<MultiPoint1>::type point1_type;
84 std::vector<point1_type> points1(boost::begin(multipoint1),
85 boost::end(multipoint1));
87 std::sort(points1.begin(), points1.end(), detail::relate::less());
89 typedef unary_disjoint_predicate
91 typename std::vector<point1_type>::const_iterator
94 return check_iterator_range
97 >::apply(boost::begin(multipoint2),
98 boost::end(multipoint2),
99 predicate_type(points1.begin(), points1.end()));
104 template <typename MultiPoint, typename Linear>
105 class multipoint_linear
108 // structs for partition -- start
111 template <typename Box, typename Geometry>
112 static inline void apply(Box& total, Geometry const& geometry)
114 geometry::expand(total, geometry::return_envelope<Box>(geometry));
121 template <typename Box, typename Geometry>
122 static inline bool apply(Box const& box, Geometry const& geometry)
124 return ! dispatch::disjoint<Geometry, Box>::apply(geometry, box);
128 class item_visitor_type
131 item_visitor_type() : m_intersection_found(false) {}
133 template <typename Item1, typename Item2>
134 inline void apply(Item1 const& item1, Item2 const& item2)
136 if (! m_intersection_found
137 && ! dispatch::disjoint<Item1, Item2>::apply(item1, item2))
139 m_intersection_found = true;
143 inline bool intersection_found() const { return m_intersection_found; }
146 bool m_intersection_found;
148 // structs for partition -- end
153 typedef geometry::segment_iterator<Linear const> const_iterator;
154 typedef const_iterator iterator;
156 segment_range(Linear const& linear)
160 const_iterator begin() const
162 return geometry::segments_begin(m_linear);
165 const_iterator end() const
167 return geometry::segments_end(m_linear);
171 Linear const& m_linear;
175 static inline bool apply(MultiPoint const& multipoint, Linear const& linear)
177 item_visitor_type visitor;
181 geometry::model::box<typename point_type<MultiPoint>::type>,
184 >::apply(multipoint, segment_range(linear), visitor);
186 return ! visitor.intersection_found();
189 static inline bool apply(Linear const& linear, MultiPoint const& multipoint)
191 return apply(multipoint, linear);
196 }} // namespace detail::disjoint
197 #endif // DOXYGEN_NO_DETAIL
202 #ifndef DOXYGEN_NO_DISPATCH
207 template <typename Point, typename MultiPoint, std::size_t DimensionCount>
210 Point, MultiPoint, DimensionCount, point_tag, multi_point_tag, false
211 > : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Point>
215 template <typename MultiPoint, typename Segment, std::size_t DimensionCount>
218 MultiPoint, Segment, DimensionCount, multi_point_tag, segment_tag, false
219 > : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Segment>
223 template <typename MultiPoint, typename Box, std::size_t DimensionCount>
226 MultiPoint, Box, DimensionCount, multi_point_tag, box_tag, false
227 > : detail::disjoint::multirange_constant_size_geometry<MultiPoint, Box>
233 typename MultiPoint1,
234 typename MultiPoint2,
235 std::size_t DimensionCount
239 MultiPoint1, MultiPoint2, DimensionCount,
240 multi_point_tag, multi_point_tag, false
243 static inline bool apply(MultiPoint1 const& multipoint1,
244 MultiPoint2 const& multipoint2)
246 if ( boost::size(multipoint2) < boost::size(multipoint1) )
248 return detail::disjoint::multipoint_multipoint
250 MultiPoint2, MultiPoint1
251 >::apply(multipoint2, multipoint1);
254 return detail::disjoint::multipoint_multipoint
256 MultiPoint1, MultiPoint2
257 >::apply(multipoint1, multipoint2);
262 template <typename Linear, typename MultiPoint, std::size_t DimensionCount>
265 Linear, MultiPoint, DimensionCount, linear_tag, multi_point_tag, false
266 > : detail::disjoint::multipoint_linear<MultiPoint, Linear>
270 template <typename MultiPoint, typename Linear, std::size_t DimensionCount>
273 MultiPoint, Linear, DimensionCount, multi_point_tag, linear_tag, false
274 > : detail::disjoint::multipoint_linear<MultiPoint, Linear>
278 } // namespace dispatch
279 #endif // DOXYGEN_NO_DISPATCH
282 }} // namespace boost::geometry
286 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_MULTIPOINT_GEOMETRY_HPP