1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. 4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. 5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. 6 // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. 7 8 // This file was modified by Oracle on 2013-2018. 9 // Modifications copyright (c) 2013-2018, 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_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP 22 #define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP 23 24 #include <cstddef> 25 26 #include <boost/geometry/core/cs.hpp> 27 28 #include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp> 29 #include <boost/geometry/strategies/disjoint.hpp> 30 31 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> 32 #include <boost/geometry/util/select_most_precise.hpp> 33 34 35 namespace boost { namespace geometry { namespace strategy { namespace disjoint 36 { 37 38 #ifndef DOXYGEN_NO_DETAIL 39 namespace detail 40 { 41 42 struct box_box_on_spheroid 43 { 44 template <typename Box1, typename Box2> applyboost::geometry::strategy::disjoint::detail::box_box_on_spheroid45 static inline bool apply(Box1 const& box1, Box2 const& box2) 46 { 47 typedef typename geometry::select_most_precise 48 < 49 typename coordinate_type<Box1>::type, 50 typename coordinate_type<Box2>::type 51 >::type calc_t; 52 typedef typename geometry::detail::cs_angular_units<Box1>::type units_t; 53 typedef math::detail::constants_on_spheroid<calc_t, units_t> constants; 54 55 calc_t const b1_min = get<min_corner, 0>(box1); 56 calc_t const b1_max = get<max_corner, 0>(box1); 57 calc_t const b2_min = get<min_corner, 0>(box2); 58 calc_t const b2_max = get<max_corner, 0>(box2); 59 60 // min <= max <=> diff >= 0 61 calc_t const diff1 = b1_max - b1_min; 62 calc_t const diff2 = b2_max - b2_min; 63 64 // check the intersection if neither box cover the whole globe 65 if (diff1 < constants::period() && diff2 < constants::period()) 66 { 67 // calculate positive longitude translation with b1_min as origin 68 calc_t const diff_min = math::longitude_distance_unsigned<units_t>(b1_min, b2_min); 69 calc_t const b2_min_transl = b1_min + diff_min; // always right of b1_min 70 calc_t b2_max_transl = b2_min_transl - constants::period() + diff2; 71 72 // if the translation is too close then use the original point 73 // note that math::abs(b2_max_transl - b2_max) takes values very 74 // close to k*2*constants::period() for k=0,1,2,... 75 if (math::abs(b2_max_transl - b2_max) < constants::period() / 2) 76 { 77 b2_max_transl = b2_max; 78 } 79 80 if (b2_min_transl > b1_max // b2_min right of b1_max 81 && b2_max_transl < b1_min) // b2_max left of b1_min 82 { 83 return true; 84 } 85 } 86 87 return box_box 88 < 89 Box1, Box2, 1 90 >::apply(box1, box2); 91 } 92 }; 93 94 } // namespace detail 95 #endif // DOXYGEN_NO_DETAIL 96 97 98 struct spherical_box_box 99 { 100 template <typename Box1, typename Box2> applyboost::geometry::strategy::disjoint::spherical_box_box101 static inline bool apply(Box1 const& box1, Box2 const& box2) 102 { 103 return detail::box_box_on_spheroid::apply(box1, box2); 104 } 105 }; 106 107 108 namespace services 109 { 110 111 template <typename Box1, typename Box2, int TopDim1, int TopDim2> 112 struct default_strategy<Box1, Box2, box_tag, box_tag, TopDim1, TopDim2, spherical_equatorial_tag, spherical_equatorial_tag> 113 { 114 typedef disjoint::spherical_box_box type; 115 }; 116 117 template <typename Box1, typename Box2, int TopDim1, int TopDim2> 118 struct default_strategy<Box1, Box2, box_tag, box_tag, TopDim1, TopDim2, spherical_polar_tag, spherical_polar_tag> 119 { 120 typedef disjoint::spherical_box_box type; 121 }; 122 123 template <typename Box1, typename Box2, int TopDim1, int TopDim2> 124 struct default_strategy<Box1, Box2, box_tag, box_tag, TopDim1, TopDim2, geographic_tag, geographic_tag> 125 { 126 typedef disjoint::spherical_box_box type; 127 }; 128 129 } // namespace services 130 131 }}}} // namespace boost::geometry::strategy::disjoint 132 133 134 #endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP 135