From 4444357697c4533da8b335191b463fb6bddbb464 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 9 Mar 2016 04:25:02 +0100 Subject: [PATCH] [disjoint] Support non-cartesian CSes for Pt/Box and Box/Box. For Point/Box use part of the implementation of point_in_box covered_by strategy. --- .../algorithms/detail/disjoint/box_box.hpp | 76 ++++++++++++++++--- .../algorithms/detail/disjoint/point_box.hpp | 63 ++++++--------- 2 files changed, 88 insertions(+), 51 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp index 6074af982..a385425d6 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2015. -// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2016. +// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -28,6 +28,9 @@ #include +#include +#include + namespace boost { namespace geometry { @@ -39,7 +42,13 @@ namespace detail { namespace disjoint template < typename Box1, typename Box2, - std::size_t Dimension, std::size_t DimensionCount + std::size_t Dimension = 0, + std::size_t DimensionCount = dimension::value, + typename CSTag = typename tag_cast + < + typename cs_tag::type, + spherical_tag + >::type > struct box_box { @@ -62,8 +71,8 @@ struct box_box }; -template -struct box_box +template +struct box_box { static inline bool apply(Box1 const& , Box2 const& ) { @@ -72,6 +81,57 @@ struct box_box }; +template +struct box_box +{ + static inline bool apply(Box1 const& box1, Box2 const& box2) + { + typedef typename geometry::select_most_precise + < + typename coordinate_type::type, + typename coordinate_type::type + >::type calc_t; + typedef typename coordinate_system::type::units units_t; + typedef math::detail::constants_on_spheroid constants; + + calc_t const b1_min = get(box1); + calc_t const b1_max = get(box1); + calc_t const b2_min = get(box2); + calc_t const b2_max = get(box2); + + // min <= max <=> diff >= 0 + calc_t const diff1 = b1_max - b1_min; + calc_t const diff2 = b2_max - b2_min; + + // check the intersection if neither box cover the whole globe + if (math::smaller(diff1, constants::period()) + && math::smaller(diff2, constants::period()) ) // < period + { + // calculate positive longitude translation with b1_min as origin + calc_t const c0 = 0; + calc_t diff_min = b2_min - b1_min; + math::normalize_longitude(diff_min); + if (diff_min < c0) // [-180, 180] -> [0, 360] + diff_min += constants::period(); + + calc_t const b2_min_transl = b1_min + diff_min; // always right of b1_min + + if (b2_min_transl > b1_max // b2_min right of b1_max + && b2_min_transl - constants::period() + diff2 < b1_min) // b2_max left of b1_min + { + return true; + } + } + + return box_box + < + Box1, Box2, + 1, DimensionCount + >::apply(box1, box2); + } +}; + + /*! \brief Internal utility function to detect if boxes are disjoint \note Is used from other algorithms, declared separately @@ -80,11 +140,7 @@ struct box_box template inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2) { - return box_box - < - Box1, Box2, - 0, dimension::type::value - >::apply(box1, box2); + return box_box::apply(box1, box2); } diff --git a/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp index 73b7b7099..2f1085ada 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland -// This file was modified by Oracle on 2013-2015. -// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2016. +// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -28,6 +28,7 @@ #include #include +#include namespace boost { namespace geometry { @@ -37,49 +38,19 @@ namespace detail { namespace disjoint { -template -< - typename Point, typename Box, - std::size_t Dimension, std::size_t DimensionCount -> -struct point_box -{ - static inline bool apply(Point const& point, Box const& box) - { - if (get(point) < get(box) - || get(point) > get(box)) - { - return true; - } - return point_box - < - Point, Box, - Dimension + 1, DimensionCount - >::apply(point, box); - } -}; - - -template -struct point_box -{ - static inline bool apply(Point const& , Box const& ) - { - return false; - } -}; - /*! \brief Internal utility function to detect if point/box are disjoint */ template inline bool disjoint_point_box(Point const& point, Box const& box) { - return detail::disjoint::point_box - < - Point, Box, - 0, dimension::type::value - >::apply(point, box); + // ! covered_by(point, box) + return ! strategy::within::relate_point_box_loop + < + strategy::within::covered_by_range, + Point, Box, + 0, dimension::type::value + >::apply(point, box); } @@ -94,8 +65,18 @@ namespace dispatch template struct disjoint - : detail::disjoint::point_box -{}; +{ + static inline bool apply(Point const& point, Box const& box) + { + // ! covered_by(point, box) + return ! strategy::within::relate_point_box_loop + < + strategy::within::covered_by_range, + Point, Box, + 0, DimensionCount + >::apply(point, box); + } +}; } // namespace dispatch