Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:41

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
0007 
0008 // This file was modified by Oracle on 2018-2020.
0009 // Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
0010 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0011 
0012 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0013 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0014 
0015 // Use, modification and distribution is subject to the Boost Software License,
0016 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0017 // http://www.boost.org/LICENSE_1_0.txt)
0018 
0019 #ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
0020 #define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
0021 
0022 #include <array>
0023 
0024 #include <boost/core/ignore_unused.hpp>
0025 
0026 #include <boost/geometry/algorithms/assign.hpp>
0027 #include <boost/geometry/core/access.hpp>
0028 #include <boost/geometry/core/coordinate_dimension.hpp>
0029 #include <boost/geometry/strategies/covered_by.hpp>
0030 #include <boost/geometry/strategies/geographic/side.hpp>
0031 #include <boost/geometry/strategies/side.hpp>
0032 #include <boost/geometry/strategies/spherical/ssf.hpp>
0033 #include <boost/geometry/strategies/within.hpp>
0034 
0035 
0036 namespace boost { namespace geometry { namespace strategy
0037 {
0038 
0039 namespace within
0040 {
0041 
0042 #ifndef DOXYGEN_NO_DETAIL
0043 namespace detail
0044 {
0045 
0046 struct decide_within
0047 {
0048     static inline bool apply(int side, bool& result)
0049     {
0050         if (side != 1)
0051         {
0052             result = false;
0053             return false;
0054         }
0055         return true; // continue
0056     }
0057 };
0058 
0059 struct decide_covered_by
0060 {
0061     static inline bool apply(int side, bool& result)
0062     {
0063         if (side != 1)
0064         {
0065             result = side >= 0;
0066             return false;
0067         }
0068         return true; // continue
0069     }
0070 };
0071 
0072 
0073 // WARNING
0074 // This strategy is not suitable for boxes in non-cartesian CSes having edges
0075 // longer than 180deg because e.g. the SSF formula picks the side of the closer
0076 // longitude, so for long edges the side is the opposite.
0077 // Actually it is not suitable for shorter edges either because the edges of
0078 // boxes are defined by meridians and parallels, not great circles or geodesics.
0079 template <typename Decide, typename Point, typename Box, typename Strategy>
0080 inline bool point_in_box_by_side(Point const& point, Box const& box,
0081                                  Strategy const& strategy)
0082 {
0083     boost::ignore_unused(strategy);
0084 
0085     // Create (counterclockwise) array of points, the fifth one closes it
0086     // Every point should be on the LEFT side (=1), or ON the border (=0),
0087     // So >= 1 or >= 0
0088     std::array<typename point_type<Box>::type, 5> bp;
0089     geometry::detail::assign_box_corners_oriented<true>(box, bp);
0090     bp[4] = bp[0];
0091 
0092     bool result = true;
0093     for (int i = 1; i < 5; i++)
0094     {
0095         int const side = strategy.apply(point, bp[i - 1], bp[i]);
0096         if (! Decide::apply(side, result))
0097         {
0098             return result;
0099         }
0100     }
0101 
0102     return result;
0103 }
0104 
0105 
0106 } // namespace detail
0107 #endif // DOXYGEN_NO_DETAIL
0108 
0109 
0110 // There should probably be another category of geometry different than box,
0111 // e.g. rectangle or convex_ring. This strategy should probably be an
0112 // algorithm calling side strategy.
0113 
0114 template <typename CalculationType = void>
0115 struct cartesian_point_box_by_side
0116 {
0117     template <typename Point, typename Box>
0118     static inline bool apply(Point const& point, Box const& box)
0119     {
0120         using side_strategy_type
0121             = typename strategy::side::services::default_strategy
0122                 <cartesian_tag, CalculationType>::type;
0123 
0124         return within::detail::point_in_box_by_side
0125             <
0126                 within::detail::decide_within
0127             >(point, box, side_strategy_type());
0128     }
0129 };
0130 
0131 template <typename CalculationType = void>
0132 struct spherical_point_box_by_side
0133 {
0134     template <typename Point, typename Box>
0135     static inline bool apply(Point const& point, Box const& box)
0136     {
0137         return within::detail::point_in_box_by_side
0138             <
0139                 within::detail::decide_within
0140             >(point, box,
0141               strategy::side::spherical_side_formula<CalculationType>());
0142     }
0143 };
0144 
0145 template
0146 <
0147     typename FormulaPolicy = strategy::andoyer,
0148     typename Spheroid = srs::spheroid<double>,
0149     typename CalculationType = void
0150 >
0151 struct geographic_point_box_by_side
0152 {
0153     geographic_point_box_by_side() = default;
0154 
0155     explicit geographic_point_box_by_side(Spheroid const& spheroid)
0156         : m_side(spheroid)
0157     {}
0158 
0159     template <typename Point, typename Box>
0160     bool apply(Point const& point, Box const& box) const
0161     {
0162         return within::detail::point_in_box_by_side
0163             <
0164                 within::detail::decide_within
0165             >(point, box, m_side);
0166     }
0167 
0168     Spheroid const& model() const
0169     {
0170         return m_side.model();
0171     }
0172 
0173 private:
0174     strategy::side::geographic
0175         <
0176             FormulaPolicy, Spheroid, CalculationType
0177         > m_side;
0178 };
0179 
0180 
0181 } // namespace within
0182 
0183 
0184 namespace covered_by
0185 {
0186 
0187 
0188 template <typename CalculationType = void>
0189 struct cartesian_point_box_by_side
0190 {
0191     template <typename Point, typename Box>
0192     static bool apply(Point const& point, Box const& box)
0193     {
0194         using side_strategy_type
0195             = typename strategy::side::services::default_strategy
0196                 <cartesian_tag, CalculationType>::type;
0197         return within::detail::point_in_box_by_side
0198             <
0199                 within::detail::decide_covered_by
0200             >(point, box, side_strategy_type());
0201     }
0202 };
0203 
0204 template <typename CalculationType = void>
0205 struct spherical_point_box_by_side
0206 {
0207     template <typename Point, typename Box>
0208     static bool apply(Point const& point, Box const& box)
0209     {
0210         return within::detail::point_in_box_by_side
0211             <
0212                 within::detail::decide_covered_by
0213             >(point, box,
0214               strategy::side::spherical_side_formula<CalculationType>());
0215     }
0216 };
0217 
0218 template
0219 <
0220     typename FormulaPolicy = strategy::andoyer,
0221     typename Spheroid = srs::spheroid<double>,
0222     typename CalculationType = void
0223 >
0224 struct geographic_point_box_by_side
0225 {
0226     geographic_point_box_by_side() = default;
0227 
0228     explicit geographic_point_box_by_side(Spheroid const& spheroid)
0229         : m_side(spheroid)
0230     {}
0231 
0232     template <typename Point, typename Box>
0233     bool apply(Point const& point, Box const& box) const
0234     {
0235         return within::detail::point_in_box_by_side
0236             <
0237                 within::detail::decide_covered_by
0238             >(point, box, m_side);
0239     }
0240 
0241     Spheroid const& model() const
0242     {
0243         return m_side.model();
0244     }
0245 
0246 private:
0247     strategy::side::geographic
0248         <
0249             FormulaPolicy, Spheroid, CalculationType
0250         > m_side;
0251 };
0252 
0253 
0254 }
0255 
0256 
0257 }}} // namespace boost::geometry::strategy
0258 
0259 
0260 #endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP