123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_POINT_HPP
- #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_POINT_POINT_HPP
- #include <algorithm>
- #include <vector>
- #include <boost/range/empty.hpp>
- #include <boost/range/size.hpp>
- #include <boost/geometry/algorithms/detail/equals/point_point.hpp>
- #include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
- #include <boost/geometry/algorithms/detail/relate/result.hpp>
- #include <boost/geometry/policies/compare.hpp>
- namespace boost { namespace geometry
- {
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail { namespace relate {
- template <typename Point1, typename Point2>
- struct point_point
- {
- static const bool interruption_enabled = false;
- template <typename Result, typename Strategy>
- static inline void apply(Point1 const& point1, Point2 const& point2,
- Result & result,
- Strategy const& strategy)
- {
- bool equal = detail::equals::equals_point_point(point1, point2, strategy);
- if ( equal )
- {
- update<interior, interior, '0'>(result);
- }
- else
- {
- update<interior, exterior, '0'>(result);
- update<exterior, interior, '0'>(result);
- }
- update<exterior, exterior, result_dimension<Point1>::value>(result);
- }
- };
- template <typename Point, typename MultiPoint, typename EqPPStrategy>
- std::pair<bool, bool> point_multipoint_check(Point const& point,
- MultiPoint const& multi_point,
- EqPPStrategy const& strategy)
- {
- bool found_inside = false;
- bool found_outside = false;
-
-
- auto const end = boost::end(multi_point);
- for (auto it = boost::begin(multi_point); it != end; ++it)
- {
- bool ii = detail::equals::equals_point_point(point, *it, strategy);
- if (ii)
- {
- found_inside = true;
- }
- else
- {
- found_outside = true;
- }
- if (found_inside && found_outside)
- {
- break;
- }
- }
- return std::make_pair(found_inside, found_outside);
- }
- template <typename Point, typename MultiPoint, bool Transpose = false>
- struct point_multipoint
- {
- static const bool interruption_enabled = false;
- template <typename Result, typename Strategy>
- static inline void apply(Point const& point, MultiPoint const& multi_point,
- Result & result,
- Strategy const& strategy)
- {
- if ( boost::empty(multi_point) )
- {
-
- update<interior, exterior, '0', Transpose>(result);
- return;
- }
- std::pair<bool, bool> rel = point_multipoint_check(point, multi_point, strategy);
- if ( rel.first )
- {
- update<interior, interior, '0', Transpose>(result);
- if ( rel.second )
- {
- update<exterior, interior, '0', Transpose>(result);
- }
- }
- else
- {
- update<interior, exterior, '0', Transpose>(result);
- update<exterior, interior, '0', Transpose>(result);
- }
- update<exterior, exterior, result_dimension<Point>::value, Transpose>(result);
- }
- };
- template <typename MultiPoint, typename Point>
- struct multipoint_point
- {
- static const bool interruption_enabled = false;
- template <typename Result, typename Strategy>
- static inline void apply(MultiPoint const& multi_point, Point const& point,
- Result & result,
- Strategy const& strategy)
- {
- point_multipoint<Point, MultiPoint, true>::apply(point, multi_point, result, strategy);
- }
- };
- template <typename MultiPoint1, typename MultiPoint2>
- struct multipoint_multipoint
- {
- static const bool interruption_enabled = true;
- template <typename Result, typename Strategy>
- static inline void apply(MultiPoint1 const& multi_point1, MultiPoint2 const& multi_point2,
- Result & result,
- Strategy const& )
- {
- {
-
- bool empty1 = boost::empty(multi_point1);
- bool empty2 = boost::empty(multi_point2);
- if ( empty1 && empty2 )
- {
- return;
- }
- else if ( empty1 )
- {
- update<exterior, interior, '0'>(result);
- return;
- }
- else if ( empty2 )
- {
- update<interior, exterior, '0'>(result);
- return;
- }
- }
-
- if ( boost::size(multi_point1) < boost::size(multi_point2) )
- {
- search_both<false, Strategy>(multi_point1, multi_point2, result);
- }
- else
- {
- search_both<true, Strategy>(multi_point2, multi_point1, result);
- }
- update<exterior, exterior, result_dimension<MultiPoint1>::value>(result);
- }
- template <bool Transpose, typename Strategy, typename MPt1, typename MPt2, typename Result>
- static inline void search_both(MPt1 const& first_sorted_mpt, MPt2 const& first_iterated_mpt,
- Result & result)
- {
- if ( relate::may_update<interior, interior, '0'>(result)
- || relate::may_update<interior, exterior, '0'>(result)
- || relate::may_update<exterior, interior, '0'>(result) )
- {
-
- bool const is_disjoint = search<Transpose, Strategy>(first_sorted_mpt, first_iterated_mpt, result);
- if (is_disjoint || BOOST_GEOMETRY_CONDITION(result.interrupt) )
- {
- return;
- }
- }
- if ( relate::may_update<interior, interior, '0'>(result)
- || relate::may_update<interior, exterior, '0'>(result)
- || relate::may_update<exterior, interior, '0'>(result) )
- {
-
- search<! Transpose, Strategy>(first_iterated_mpt, first_sorted_mpt, result);
- }
- }
- template <bool Transpose,
- typename Strategy,
- typename SortedMultiPoint,
- typename IteratedMultiPoint,
- typename Result>
- static inline bool search(SortedMultiPoint const& sorted_mpt,
- IteratedMultiPoint const& iterated_mpt,
- Result & result)
- {
-
- typedef typename geometry::point_type<SortedMultiPoint>::type point_type;
- typedef geometry::less<void, -1, Strategy> less_type;
- std::vector<point_type> points(boost::begin(sorted_mpt), boost::end(sorted_mpt));
- less_type const less = less_type();
- std::sort(points.begin(), points.end(), less);
- bool found_inside = false;
- bool found_outside = false;
-
- for (auto it = boost::begin(iterated_mpt); it != boost::end(iterated_mpt); ++it)
- {
- bool ii = std::binary_search(points.begin(), points.end(), *it, less);
- if (ii)
- {
- found_inside = true;
- }
- else
- {
- found_outside = true;
- }
- if (found_inside && found_outside)
- {
- break;
- }
- }
- if ( found_inside )
- {
- update<interior, interior, '0', Transpose>(result);
- if ( found_outside )
- {
- update<exterior, interior, '0', Transpose>(result);
- }
- }
- else
- {
- update<interior, exterior, '0', Transpose>(result);
- update<exterior, interior, '0', Transpose>(result);
- }
-
- return ! found_inside;
- }
- };
- }}
- #endif
- }}
- #endif
|